1036: [ZJOI2008]树的统计Count - BZOJ
2014-04-06 16:58
316 查看
Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
裸树链剖分,我就不多说了,附入门教程
View Code
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
裸树链剖分,我就不多说了,附入门教程
const maxn=30010; type node=record son:array[0..1]of longint; sum,max,left,right,mid:longint; end; var n,m,num,tot,xx,ll,rr,goal:longint; tree:array[0..maxn*2]of node; first,fa,dep,son,size,w,top,root:array[0..maxn]of longint; next,last:array[0..maxn*2]of longint; procedure insert(x,y:longint); begin inc(num); last[num]:=y; next[num]:=first[x]; first[x]:=num; end; procedure dfs1(x,d,f:longint); var i:longint; begin dep[x]:=d; fa[x]:=f; size[x]:=1; i:=first[x]; while i<>0 do begin if last[i]<>f then begin dfs1(last[i],d+1,x); if size[last[i]]>size[son[x]] then son[x]:=last[i]; inc(size[x],size[last[i]]); end; i:=next[i]; end; end; procedure build(l,r:longint); var now:longint; begin inc(tot); now:=tot; with tree[now] do begin left:=l; right:=r; if l=r then exit; mid:=(l+r)>>1; son[0]:=tot+1; build(l,mid); son[1]:=tot+1; build(mid+1,r); end; end; procedure dfs2(x,t,ww:longint); var i:longint; begin w[x]:=ww; top[x]:=t; if son[x]=0 then begin root[x]:=tot+1; build(1,ww); exit; end else begin dfs2(son[x],t,ww+1); root[x]:=root[son[x]]; end; i:=first[x]; while i<>0 do begin if (last[i]<>fa[x]) and (last[i]<>son[x]) then dfs2(last[i],last[i],1); i:=next[i]; end; end; procedure change(now:longint); begin with tree[now] do begin if left=right then begin sum:=goal; max:=goal; exit; end; if xx<=mid then change(son[0]) else change(son[1]); if tree[son[0]].max>tree[son[1]].max then max:=tree[son[0]].max else max:=tree[son[1]].max; sum:=tree[son[0]].sum+tree[son[1]].sum; end; end; function getsum(now:longint):longint; begin with tree[now] do begin if (ll<=left) and (rr>=right) then exit(sum); if rr<=mid then exit(getsum(son[0])); if ll>mid then exit(getsum(son[1])); exit(getsum(son[0])+getsum(son[1])); end; end; function getmax(now:longint):longint; var s:longint; begin with tree[now] do begin if (ll<=left) and (rr>=right) then exit(max); if rr<=mid then exit(getmax(son[0])); if ll>mid then exit(getmax(son[1])); getmax:=getmax(son[0]); s:=getmax(son[1]); if s>getmax then getmax:=s; end; end; procedure init; var i,x,y:longint; begin read(n); for i:=1 to n-1 do begin read(x,y); insert(x,y); insert(y,x); end; dfs1(1,1,0); dfs2(1,1,1); for i:=1 to n do begin read(goal); xx:=w[i]; change(root[i]); end; end; procedure work; var i,ans,s,x,y:longint; s1,s2:char; begin read(m); for i:=1 to m do begin read(s2); while s2<>' ' do begin s1:=s2; read(s2); end; read(x,y); case s1 of 'E':begin goal:=y; xx:=w[x]; change(root[x]); end; 'X':begin ans:=-300000; while top[x]<>top[y] do begin if dep[top[x]]<dep[top[y]] then begin s:=x;x:=y;y:=s; end; ll:=1; rr:=w[x]; s:=getmax(root[x]); if s>ans then ans:=s; x:=fa[top[x]]; end; if dep[x]<dep[y] then begin s:=x;x:=y;y:=s; end; ll:=w[y]; rr:=w[x]; s:=getmax(root[x]); if s>ans then ans:=s; writeln(ans); end; 'M':begin ans:=0; while top[x]<>top[y] do begin if dep[top[x]]<dep[top[y]] then begin s:=x;x:=y;y:=s; end; ll:=1; rr:=w[x]; inc(ans,getsum(root[x])); x:=fa[top[x]]; end; if dep[x]<dep[y] then begin s:=x;x:=y;y:=s; end; ll:=w[y]; rr:=w[x]; inc(ans,getsum(root[x])); writeln(ans); end; end; end; end; begin init; work; end.
View Code
相关文章推荐
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ1036: [ZJOI2008]树的统计Count
- bzoj 1036: [ZJOI2008]树的统计Count (树链剖分)
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
- bzoj1036: [ZJOI2008]树的统计Count(树剖模版)
- bzoj1036 [ZJOI2008]树的统计Count
- Bzoj 1036: [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】
- bzoj1036 [ZJOI2008]树的统计Count (树链剖分|Link Cut Tree)
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分裸题)
- BZOJ 1036: [ZJOI2008]树的统计Count
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分入门系列)
- HYSBZ/BZOJ 1036 [ZJOI2008] 树的统计Count - 动态树LCT
- BZOJ 1036 [ZJOI2008]树的统计Count | 树链剖分模板
- bzoj1036: [ZJOI2008]树的统计Count - 树链剖分
- bzoj1036:[ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count (LCT题解)
- bzoj 1036: [ZJOI2008]树的统计Count
- 树链剖分基础模板(BZOJ1036[ZJOI2008]树的统计Count)
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )