SPOJ QTREE 樹鏈剖分

2021-09-12 10:02:33 字數 1880 閱讀 7372

樹鏈剖分學習

核心:節點u的輕兒子為v   輕兒子的性質:size[v] <= size[u] / 2

故:每走一條輕鏈,節點數減少一半

又因:兩個節點之間的路徑,必為重鏈和輕邊交替

故:從根結點到樹上任意點經過的輕邊以及重鏈都不會超過logn條

樹鏈剖分模版題

題意:有一棵n個節點的樹(1<=n<=10000),n-1條邊,邊的編號為1~n-1,每條邊有乙個權值,要求模擬兩種操作:

1:query x y 求節點x和節點y之間的路徑中權值最大的邊。

2:change p k修改第p條邊的權值為k。

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;78

const

int n=10010;9

char s[10

];10

struct

trnodet[2*n];

13struct

nodea[2*n],b[n];

16int

n,tl,z,len;

17int

first[n],tot[n],son[n],fa[n],dep[n],ys[n],top[n];

1819

int maxx(int x,int y)

2021

void ins(int x,int y,int

d)22

2728

int build_tree(int l,int

r)29

39return

x;40}41

42void change(int x,int p,int

c)43

45int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>1;46

if(p<=mid) change(lc,p,c);

47else

change(rc,p,c);

48 t[x].c=maxx(t[lc].c,t[rc].c);49}

5051

int query(int x,int l,int

r)52

5960

void dfs1(int

x)6173}

7475

void dfs2(int x,int

tp)7685}

8687

int solve(int x,int

y)88

96if(x==y) return

ans;

97else

98102

}103

104int

main()

105122 dfs1(1

);123 dfs2(1,1

);124 build_tree(1

,z);

125for(int i=1;iif(dep[b[i].x]>dep[b[i].y]) swap(b[i].x,b[i].y);

126for(int i=1;i1

,ys[b[i].y],b[i].d);

127while(1

)128

136if(s[0]=='c'

)137

141if(s[0]=='

d') break

;142

}143

}144

return0;

145 }

posted @

2016-08-07 14:21

攔路雨偏似雪花 閱讀(

...)

編輯收藏

SPOJ QTree5 樹鏈剖分

感覺之前拿點分治水過心裡過意不去,mdzz,我還是打了乙份樹鏈剖分的code,具體方法與qtree4相同 詳見 維護線段樹的合併時的值。include define mid l r 1 define pf push front using namespace std const int n 1e5 ...

SPOJ QTREE2 樹鏈剖分

題意 有一棵n個節點的樹 1 n 10000 n 1條邊,邊的編號為1 n 1,每條邊有乙個權值,要求模擬兩種操作 1 dist a b 求 點a到點b之間的距離 2 kth a b k 求從a出發到b遇到的第k個節點的編號 qtree系列的第二題。求dist就不用說啦,主要是求第k個。方法一 我是...

SPOJ QTREE2 樹鏈剖分

題意 有一棵n個節點的樹 1 n 10000 n 1條邊,邊的編號為1 n 1,每條邊有乙個權值,要求模擬兩種操作 1 dist a b 求 點a到點b之間的距離 2 kth a b k 求從a出發到b遇到的第k個節點的編號 qtree系列的第二題。求dist就不用說啦,主要是求第k個。方法一 我是...