樹狀陣列 DFS序 Apple Tree

2021-09-24 02:28:04 字數 1658 閱讀 9648

題目鏈結

output

for every inquiry, output the correspond answer per line.

sample input

31 2

1 33

q 1c 2

q 1sample output32

題意:就是一棵蘋果樹,二叉樹;

樹有n個叉子,它們通過分支連線。卡卡將叉子編號為1到n,根始終編號為1.蘋果將在叉子上生長,兩個蘋果不會在同乙個叉子上生長。

c x」表示叉x上的蘋果存在已經改變。即如果叉子上有蘋果,那麼卡卡就會選擇它;否則乙個新的蘋果在空叉上長大。

「q x」表示查詢fork x上方子樹中的蘋果數量,包括叉子x上的蘋果(如果存在)

注意樹的開頭是蘋果

對於每個查詢,輸出每行的相應答案。

按照題意來說,就是對樹上節點的更新和查詢求和,不同的是,查詢時,我們是對於x位置上方的蘋果的數量,比如下圖,我們對於位置x是c[4],那麼我們要得到的值是 c[4]+c[8];

解題思路:

理解了題意,明顯就可以知道是用樹狀陣列,或者是線段樹應該也可以。

當然,這題是要用到dfs序.

那我們在這裡就講一下什麼是樹的dfs序;簡單的說就是dfs時遍歷的順序;

dfs序就是將樹形結構轉化為線性結構,用dfs遍歷一遍這棵樹,進入到x節點有乙個up時間戳,遞迴退出時有乙個out 時間戳,x節點的兩個時間戳之間遍歷到的點,就是根為x的子樹的所有節點,他們的dfs進入的時間戳是遞增的。同時兩個時間戳構成了乙個區間,x節點在這段區間的最左端,這個區間就是一棵根節點為x的子樹,對於區間的操作就是其他維護方式的應用了。

時間戳:是乙份能夠表示乙份資料在乙個特定時間點已經存在的完整的可驗證的資料;

比如下圖:

1:建樹,這裡資料比較大,我們可以用乙個容器vector

2:dfs序

3.樹狀陣列常規操作

4:輸入,輸入;

#include#include#include#includeusing namespace std;

const int num=100005;

vector> g(num);//c++ g(num) 即g[num];//這個用vectorg(num)會超時

int up[num],out[num];//進入的時間戳 //出去的時間戳

bool mark[num];//還有這個bool 而不能用int 用int會wa;

int time,n;

int tree[num];

void dfs(int k,int befk)//dfs序

return sum;

}int main()

dfs(1,-1);//dfs序;

for(int i=1; i<=n; i++)//

scanf("%d",&m);

for(int i=0; i

else

}return 0;

}

dfs序 樹狀陣列

the first line contains an integer n n 100,000 which is the number of the forks in the tree.output for every inquiry,output the correspond answer per ...

Apple Tree 樹狀陣列 dfs序

description input output for every inquiry,output the correspond answer per line.sample input 31 2 1 33 q 1c 2 q 1sample output32 sourcepoj monthly 20...

poj 3321(dfs序 樹狀陣列)

第一次知道dfs序這個東西,可以維護樹上的任意乙個節點,以這個節點為根的子樹上的所有節點的標號。是連續的一段區間。一棵子樹的所有節點在dfs序裡是連續一段,主要就是利用這個性質來解題 然後就是樹狀陣列維護區間內蘋果的數量 另外這個題很卡時間,我用了輸入輸出掛才過 include includeusi...