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
裸树链剖分,我就不多说了,附入门教程
1 const 2 maxn=30010; 3 type 4 node=record 5 son:array[0..1]of longint; 6 sum,max,left,right,mid:longint; 7 end; 8 var 9 n,m,num,tot,xx,ll,rr,goal:longint; 10 tree:array[0..maxn*2]of node; 11 first,fa,dep,son,size,w,top,root:array[0..maxn]of longint; 12 next,last:array[0..maxn*2]of longint; 13 14 procedure insert(x,y:longint); 15 begin 16 inc(num); 17 last[num]:=y; 18 next[num]:=first[x]; 19 first[x]:=num; 20 end; 21 22 procedure dfs1(x,d,f:longint); 23 var 24 i:longint; 25 begin 26 dep[x]:=d; 27 fa[x]:=f; 28 size[x]:=1; 29 i:=first[x]; 30 while i<>0 do 31 begin 32 if last[i]<>f then 33 begin 34 dfs1(last[i],d+1,x); 35 if size[last[i]]>size[son[x]] then son[x]:=last[i]; 36 inc(size[x],size[last[i]]); 37 end; 38 i:=next[i]; 39 end; 40 end; 41 42 procedure build(l,r:longint); 43 var 44 now:longint; 45 begin 46 inc(tot); 47 now:=tot; 48 with tree[now] do 49 begin 50 left:=l; 51 right:=r; 52 if l=r then exit; 53 mid:=(l+r)>>1; 54 son[0]:=tot+1; 55 build(l,mid); 56 son[1]:=tot+1; 57 build(mid+1,r); 58 end; 59 end; 60 61 procedure dfs2(x,t,ww:longint); 62 var 63 i:longint; 64 begin 65 w[x]:=ww; 66 top[x]:=t; 67 if son[x]=0 then 68 begin 69 root[x]:=tot+1; 70 build(1,ww); 71 exit; 72 end 73 else 74 begin 75 dfs2(son[x],t,ww+1); 76 root[x]:=root[son[x]]; 77 end; 78 i:=first[x]; 79 while i<>0 do 80 begin 81 if (last[i]<>fa[x]) and (last[i]<>son[x]) then dfs2(last[i],last[i],1); 82 i:=next[i]; 83 end; 84 end; 85 86 procedure change(now:longint); 87 begin 88 with tree[now] do 89 begin 90 if left=right then 91 begin 92 sum:=goal; 93 max:=goal; 94 exit; 95 end; 96 if xx<=mid then change(son[0]) 97 else change(son[1]); 98 if tree[son[0]].max>tree[son[1]].max then max:=tree[son[0]].max 99 else max:=tree[son[1]].max; 100 sum:=tree[son[0]].sum+tree[son[1]].sum; 101 end; 102 end; 103 104 function getsum(now:longint):longint; 105 begin 106 with tree[now] do 107 begin 108 if (ll<=left) and (rr>=right) then exit(sum); 109 if rr<=mid then exit(getsum(son[0])); 110 if ll>mid then exit(getsum(son[1])); 111 exit(getsum(son[0])+getsum(son[1])); 112 end; 113 end; 114 115 function getmax(now:longint):longint; 116 var 117 s:longint; 118 begin 119 with tree[now] do 120 begin 121 if (ll<=left) and (rr>=right) then exit(max); 122 if rr<=mid then exit(getmax(son[0])); 123 if ll>mid then exit(getmax(son[1])); 124 getmax:=getmax(son[0]); 125 s:=getmax(son[1]); 126 if s>getmax then getmax:=s; 127 end; 128 end; 129 130 procedure init; 131 var 132 i,x,y:longint; 133 begin 134 read(n); 135 for i:=1 to n-1 do 136 begin 137 read(x,y); 138 insert(x,y); 139 insert(y,x); 140 end; 141 dfs1(1,1,0); 142 dfs2(1,1,1); 143 for i:=1 to n do 144 begin 145 read(goal); 146 xx:=w[i]; 147 change(root[i]); 148 end; 149 end; 150 151 procedure work; 152 var 153 i,ans,s,x,y:longint; 154 s1,s2:char; 155 begin 156 read(m); 157 for i:=1 to m do 158 begin 159 read(s2); 160 while s2<>' ' do 161 begin 162 s1:=s2; 163 read(s2); 164 end; 165 read(x,y); 166 case s1 of 167 'E':begin 168 goal:=y; 169 xx:=w[x]; 170 change(root[x]); 171 end; 172 'X':begin 173 ans:=-300000; 174 while top[x]<>top[y] do 175 begin 176 if dep[top[x]]<dep[top[y]] then 177 begin 178 s:=x;x:=y;y:=s; 179 end; 180 ll:=1; 181 rr:=w[x]; 182 s:=getmax(root[x]); 183 if s>ans then ans:=s; 184 x:=fa[top[x]]; 185 end; 186 if dep[x]<dep[y] then 187 begin 188 s:=x;x:=y;y:=s; 189 end; 190 ll:=w[y]; 191 rr:=w[x]; 192 s:=getmax(root[x]); 193 if s>ans then ans:=s; 194 writeln(ans); 195 end; 196 'M':begin 197 ans:=0; 198 while top[x]<>top[y] do 199 begin 200 if dep[top[x]]<dep[top[y]] then 201 begin 202 s:=x;x:=y;y:=s; 203 end; 204 ll:=1; 205 rr:=w[x]; 206 inc(ans,getsum(root[x])); 207 x:=fa[top[x]]; 208 end; 209 if dep[x]<dep[y] then 210 begin 211 s:=x;x:=y;y:=s; 212 end; 213 ll:=w[y]; 214 rr:=w[x]; 215 inc(ans,getsum(root[x])); 216 writeln(ans); 217 end; 218 end; 219 end; 220 end; 221 222 begin 223 init; 224 work; 225 end.