poj 3321 Apple Tree(樹狀陣列)

2021-06-26 16:47:03 字數 1078 閱讀 4420

輝煌北大的月賽題質量真高啊,這種樹狀陣列真難想到。

樹狀陣列的基本用法是區間,單點的應用,起初這個怎麼都想不到如何套用到樹狀陣列。

轉化方法是 將樹上的節點資訊查詢,轉為深度優先中節點順序(代表結點編號)。進結點與出結點分別代表該結點管轄範圍。

題目大意級是說,給你一顆樹,最初每個節點上都有乙個蘋果,有兩種操作:修改(即修改某乙個節點,修改時這乙個節點蘋果從有到無,或從無到有)和查詢(查詢某乙個節點他的子樹上有多少個蘋果)。

由於此題資料比較大(n<=10^5),而且不是標準的二叉樹,所以這裡我們隊每乙個節點重新編號,另外為每乙個節點賦乙個左值和乙個右值,表示這個節點的管轄範圍。

也就是dfs搜尋的時候做標記的過程,這樣新的編號為1~6的節點所管轄的範圍分別就是[1,6]  [2,4]   [3,3]  [4,4]  [5,6]  [6,6],其中左邊的是左值,右邊的是右值,節點1的區間是[1,6],正好這棵子樹有6個節點,其他也一樣

#include#include#include#include#include#include#includeusing namespace std;

#define n 100010

int n,m;

int lowbit(int x)

void update(int *arr,int r,int num)

int getsum(int *arr,int r)

int head[n];

int next[n];

int netb[n];

int deh1[n];

int deh2[n];

int cnt,depth;

int arr[n];

int a[n];

void init()

void add(int u,int v)

void dfs(int u)

deh2[u]=depth;//代表右

}int main()

{ int i,j,k,u,v,m;

char str[10];

while(~scanf("%d",&n))

{ init();

for(i=1;i

POJ 3321 樹狀陣列

題意 給定一棵樹,某些節點上有蘋果,多次詢問各子樹上的節點數,並且在詢問的中途隨時可能新增和刪除蘋果。分析 dfs遍歷樹的同時,對每個點標註時間,每個點有乙個開始時間和乙個結束時間,把這兩個時間當做下標,該點的蘋果個數 1或0 填入陣列的兩個對應位。子樹中結點的時間段一定是根節點時間段的子段,所以求...

poj 3321 樹狀陣列

首先對數進行dfs一下,前序優先遍歷,這樣做的目的是令節點i的子節點的編號組成的集合是一段連續的數,這樣在查詢的時候就能夠用樹狀陣列來查詢連續的區間的和 ac 如下 include include include include using namespace std const int max n...

POJ 3321 dfs 樹狀陣列

1.題目鏈結。題目大意 一棵樹上的每乙個節點在初始的時候都長了乙個蘋果,然後有這樣的兩種操作 1 q x 詢問以x為根節點的子樹上蘋果的數量 2 c x把標號為x除的狀態改變。狀態改變的意思就是原來這裡有蘋果,就變沒,原來沒有就長出來乙個,保證每個節點最多乙個蘋果。2.首先我們肯定沒有辦法離線所有的...