DFS序 及 手動擴棧指令

2021-08-02 03:08:27 字數 2209 閱讀 1771

概念

dfs序是轉樹型結構為線型結構的經典方法。

具體實現網上優秀部落格很多,就不贅述了…

因為涉及dfs,同時此類題普遍節點的規模都在1e5以上,而hdoj好像是基於windows的伺服器,很容易爆棧,故我們需要新增乙個手動擴棧指令,並用c++提交。

#pragma comment(linker, 「/stack:1024000000,1024000000」)

hdoj 3887

題意很簡單,但思路卻困了我很久,一直糾結於如何解決不同子樹相互影響的問題。

但其實由dfs序的性質,假設存在某乙個節點x

當搜尋到x時,之前搜尋到的節點一定不屬於x的子樹,此時我們用樹狀陣列維護此前出現過的節點的標號,然後查詢小於x的標號的節點數量 num_1

當搜尋完x的子節點後,樹狀陣列裡面會包含x的succeeding nodes即後繼節點的資訊,再查詢小於x的標號的節點數量num_2

然後易得: f[x] = num_2 - num_1

**:

#pragma comment(linker, "/stack:1024000000,1024000000")

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

typedef long long ll;

#define lson rt<<1

#define rson rt<<1|1

const int a = 1e5 + 10;

class bit

void update(int pos,int val)

}bit;

class pg[a<<1];

int tot,rank,head[a],ans[a];

inline void init()

inline void add(int u,int v)

void dfs(int u,int pre)

int num2 = bit.query(u);

ans[u] = num2 - num1;

bit.update(u,1);

}int main()tree[a<<2];

class nodeg[a<<1];

int in[a],out[a],head[a],id[a];

int tot,rank;

int n,m;

ll dis[a],a[a];

void init()

void add(int u,int v)

void dfs(int u,int pre)

out[u] = rank;

}void push_up(int rt)

void push_down(int rt)

}void build_tree(int rt,int l,int r)

int mid = (l+r)>>1;

build_tree(lson,l,mid);

build_tree(rson,mid+1,r);

push_up(rt);

}void update(int rt,int st,int ed,ll c)

push_down(rt);

int mid = (l+r)>>1;

if(st<=mid) update(lson,st,ed,c);

if(ed> mid) update(rson,st,ed,c);

push_up(rt);

}ll query(int rt,int st,int ed)

push_down(rt);

int mid = (l+r)>>1;

ll res = -inf;

if(st<=mid) res = max(res,query(lson,st,ed));

if(ed> mid) res = max(res,query(rson,st,ed));

return res;

}int main()

for(int i=0 ;idis[0] = a[0];

dfs(0,-1);

build_tree(1,1,n);

int op;

while(m--)

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 ...

dfs序及其應用

dfs序是用來處理子樹一類問題的,可以把子樹問題轉化為區間問題,以便借助線段樹或樹狀陣列處理。根據dfs的順序來給節點編號,在進入這個節點時更新in陣列,出去的時候更新out陣列,這樣以i為根的子樹的操作就可以變成區間 in i out i 的操作了。int in 100005 out 100005...

練習記錄 dfs序)

牛客每日一題 根據根右左的遍歷順序的到dfs序,再求lis即為可以選到的最多點。利用dfs序維護每種顏色的樹,大佬部落格 需要注意的是當只能取同一邊的兩個點時,要取dfs序差值最大的兩個點,可以想出反例,但不會證明。includeusing namespace std const int maxn ...