一道普通的樹鏈剖分模板題,注意細節即可
1 #include 2 #include 3 #include 4 typedef longlong
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的路徑上的節點的權值和 注意 從點...