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.

 

posted @ 2013-03-05 21:35  lbz007  阅读(260)  评论(0编辑  收藏  举报
Live2D