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