1036: [ZJOI2008]树的统计Count (树链剖分模板)
1 var 2 next,e:array[0..700000]of longint; 3 a,l,r,b:Array[0..150000]of longint; 4 aa,son,d,head,top,point,fa,size,w:array[0..300000]of longint; 5 pp,qq,opt,ll,rr,ansa,ansb,root,uu,vv,i,j,n,ee,xx:longint; 6 v:array[0..300000]of boolean; 7 ch,ch1:char; 8 function max(aa,bb:longint):longint; 9 begin 10 if (aa>bb) then exit(aa) 11 else exit(bb); 12 end; 13 procedure swap(var aaa,bbb:longint); 14 var tt:longint; 15 begin 16 tt:=aaa;aaa:=bbb;bbb:=tt; 17 end; 18 procedure dfs1(u:longint); 19 var j:longint; 20 begin 21 j:=head[u]; 22 size[u]:=1; 23 while j<>0 do 24 begin 25 if d[e[j]]=0 then 26 begin 27 d[e[j]]:=d[u]+1; 28 fa[e[j]]:=u; 29 dfs1(e[j]); 30 inc(size[u],size[e[j]]); 31 if size[e[j]]>size[son[u]] then 32 son[u]:=e[j]; 33 end; 34 j:=next[j]; 35 end; 36 end; 37 procedure dfs2(u:longint); 38 var j:longint; 39 begin 40 v[u]:=true; 41 j:=head[u]; 42 top[son[u]]:=top[u]; 43 while j<>0 do 44 begin 45 if not v[e[j]] then 46 dfs2(e[j]); 47 j:=next[j]; 48 end; 49 end; 50 procedure dfs3(u:longint); 51 var j:longint; 52 begin 53 v[u]:=true; 54 j:=head[u]; 55 inc(xx);aa[xx]:=u; 56 w[u]:=xx; 57 if (son[u]<>0)and(not v[son[u]]) then 58 dfs3(son[u]); 59 while j<>0 do 60 begin 61 if not v[e[j]] then 62 dfs3(e[j]); 63 j:=next[j]; 64 end; 65 end; 66 procedure add(u,v:longint); 67 begin 68 inc(ee); 69 e[ee]:=v; 70 next[ee]:=head[u]; 71 head[u]:=ee; 72 end; 73 procedure build(s,ll,rr:longint); 74 begin 75 l[s]:=ll;r[s]:=rr; 76 if l[s]=r[s] then 77 begin 78 inc(xx); 79 a[s]:=point[aa[xx]]; 80 b[s]:=a[s]; 81 end 82 else 83 begin 84 build(s*2,ll,(ll+rr) shr 1); 85 build(s*2+1,(ll+rr)shr 1 +1,rr); 86 a[s]:=max(a[s*2],a[s*2+1]); 87 b[s]:=b[s*2]+b[s*2+1]; 88 end; 89 end; 90 procedure change(s:longint); 91 begin 92 if l[s]=r[s] then 93 begin 94 a[s]:=rr; 95 b[s]:=rr; 96 end 97 else 98 begin 99 if ll<=r[s*2] then 100 change(s*2) 101 else change(s*2+1); 102 a[s]:=max(a[s*2],a[s*2+1]); 103 b[s]:=b[s*2]+b[s*2+1]; 104 end; 105 end; 106 procedure search(s:longint); 107 begin 108 if (l[s]>rr)or(r[s]<ll) then exit; 109 if (ll<=l[s])and(rr>=r[s]) then 110 begin 111 ansa:=max(ansa,a[s]); 112 ansb:=ansb+b[s]; 113 end 114 else 115 begin 116 search(s*2); 117 search(s*2+1); 118 end; 119 end; 120 121 function getsum(aa,bb:longint):longint; 122 var faa,fbb:longint; 123 begin 124 getsum:=0; 125 while aa<>bb do 126 begin 127 if top[aa]=aa then 128 faa:=fa[aa] 129 else faa:=top[aa]; 130 if top[bb]=bb then 131 fbb:=fa[bb] 132 else fbb:=top[bb]; 133 if d[faa]>d[fbb] then 134 begin 135 swap(aa,bb); 136 swap(faa,fbb); 137 end; 138 if TOP[AA]=TOP[BB] then 139 begin 140 if d[aa]>d[bb] then swap(aa,bb); 141 ll:=w[aa];rr:=w[bb]; 142 if ll>rr then swap(ll,rr); 143 ansb:=0; 144 search(1); 145 inc(getsum,ansb-point[aa]); 146 bb:=aa; 147 end 148 else 149 if top[bb]<>fbb then 150 begin 151 inc(getsum,point[bb]);bb:=fbb; 152 end 153 else 154 begin 155 ll:=w[fbb];rr:=w[bb]; 156 if ll>rr then swap(ll,rr); 157 ansb:=0; 158 search(1); 159 inc(getsum,ansb-point[fbb]); 160 bb:=fbb; 161 end; 162 end; 163 inc(getsum,point[aa]); 164 end; 165 166 function getmax(aa,bb:longint):longint; 167 var faa,fbb:longint; 168 begin 169 getmax:=-maxlongint; 170 while aa<>bb do 171 begin 172 if top[aa]=aa then 173 faa:=fa[aa] 174 else faa:=top[aa]; 175 if top[bb]=bb then 176 fbb:=fa[bb] 177 else fbb:=top[bb]; 178 if d[faa]>d[fbb] then 179 begin 180 swap(aa,bb); 181 swap(faa,fbb); 182 end; 183 if top[aa]=top[bb] then 184 begin 185 if d[aa]>d[bb] then swap(aa,bb); 186 ll:=w[aa];rr:=w[bb]; 187 if ll>rr then swap(ll,rr); 188 ansa:=-maxlongint; 189 search(1); 190 getmax:=max(getmax,ansa); 191 bb:=aa; 192 end 193 else 194 if top[bb]<>fbb then 195 begin 196 getmax:=max(getmax,point[bb]); bb:=fbb; 197 end 198 else 199 begin 200 ll:=w[fbb];rr:=w[bb]; 201 if ll>rr then swap(ll,rr); 202 ansa:=-maxlongint; 203 search(1); 204 getmax:=max(getmax,ansa); 205 bb:=fbb; 206 end; 207 end; 208 getmax:=max(getmax,point[aa]); 209 end; 210 211 begin 212 assign(input,'count.in');reset(input); 213 assign(output,'count.out');rewrite(output); 214 215 randomize; 216 readln(n); 217 for i:=1 to n-1 do 218 begin 219 readln(uu,vv); 220 add(uu,vv); 221 add(vv,uu); 222 end; 223 root:=random(n)+1;root:=1; 224 d[root]:=1; 225 dfs1(root); 226 for i:=1 to n do top[i]:=i; 227 dfs3(root); 228 fillchar(v,sizeof(v),false); 229 dfs2(root); 230 for i:=1 to n do 231 read(point[i]); 232 xx:=0; 233 build(1,1,n); 234 readln(opt); 235 for i:=1 to opt do 236 begin 237 read(ch,ch1); 238 if (ch='Q')and(ch1='M') then 239 begin 240 read(ch,ch,ch); 241 readln(pp,qq); 242 writeln(getmax(pp,qq)); 243 end; 244 if (ch='Q')and(ch1='S') then 245 begin 246 read(ch,ch,ch); 247 readln(pp,qq); 248 writeln(getsum(pp,qq)); 249 end; 250 if (ch='C') then 251 begin 252 read(ch,ch,ch,ch,ch); 253 readln(ll,rr); 254 point[ll]:=rr; 255 ll:=w[ll]; 256 change(1); 257 end; 258 end; 259 close(input); 260 close(output); 261 end.
-------------------------------------------------------------------------
花有重开日,人无再少年