ZJOI2008 樹的統計

2022-08-03 02:54:15 字數 1829 閱讀 8379

一道普通的樹鏈剖分模板題,注意細節即可

1 #include 2 #include 3 #include 4 typedef long

long

ll;5 inline int

read()

9while(c<='

9'&&c>='

0') ret=ret*10+c-'

0',c=getchar();

10return ret*f;11}

12using

namespace

std;

13int

n,q;

14struct

edge a[30010

<<1

];17

int head[30010

<<1],num,val[30010

];18

int fa[30010],size[30010],d[30010],son[30010],top[30010

];19

int seg[30010],rev[30010],sum[30010

<<2],maxx[30010

<<2

];20

intretsum,retmax;

21char

in[11

];22 inline void add(int

from,int

to)

27 inline void pushup(int

now)

31void dfs1(int u,int

f) 42}43

void dfs2(int u,int

f) 50

for(int i=head[u];i;i=a[i].next) 58}

59}60void build(int now,int l,int

r) 65

int mid=l+r>>1

;66 build(now<<1

,l,mid);

67 build(now<<1|1,mid+1

,r);

68pushup(now);69}

70void updata(int now,int l,int r,int x,int

v) 76

int mid=l+r>>1;77

if(x<=mid) updata(now<<1

,l,mid,x,v);

78else updata(now<<1|1,mid+1

,r,x,v);

79pushup(now);80}

81void query(int now,int l,int r,int x,int

y) 87

int mid=l+r>>1;88

if(x<=mid) query(now<<1

,l,mid,x,y);

89if(y>mid) query(now<<1|1,mid+1

,r,x,y);90}

91void find(int x,int

y) 97

if(d[x]>d[y]) swap(x,y);

98 query(1,1,seg[0

],seg[x],seg[y]);99}

100int

main()

120}

121return0;

122 }

幾個易錯點總結:

樹鏈剖分的求解過程實質上是線段樹,所以線段樹維護的相關陣列應開4倍空間

注意區分seg與rev的含義

retmax,retsum賦初值

注意第95行(個人易錯)

ZJOI 2008 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...

ZJOI2008 樹的統計

zjoi2008 樹的統計 題目描述 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到...

ZJOI2008 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...