树链剖分的基本题
详细介绍在http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
通过树链剖分我们就可以在树上做线段树操作,完成解答

  1 const inf=2147483647;
  2 type node=record
  3        po,next:longint;
  4      end;
  5      point=record
  6        max,sum:longint;
  7      end;
  8 
  9 
 10 var tree:array[0..120010] of point;
 11     size,d,fa,p,b,c,top:array[0..30010] of longint;
 12     w:array[0..80010] of node;
 13     len,i,n,m,x,y,t:longint;
 14     ch:char;
 15     s:string;
 16 
 17 function max(a,b:longint):longint;
 18   begin
 19     if a>b then exit(a) else exit(b);
 20   end;
 21 
 22 procedure update(i:longint);
 23   begin
 24     tree[i].sum:=tree[i*2].sum+tree[i*2+1].sum;
 25     tree[i].max:=max(tree[i*2].max,tree[i*2+1].max);
 26   end;
 27 
 28 procedure swap(var a,b:longint);
 29   var c:longint;
 30   begin
 31     c:=a;
 32     a:=b;
 33     b:=c;
 34   end;
 35 
 36 procedure add(x,y:longint);
 37   begin
 38     inc(len);
 39     w[len].po:=y;
 40     w[len].next:=p[x];
 41     p[x]:=len;
 42   end;
 43 
 44 procedure dfs1(x:longint);  //预处理
 45   var i,y:longint;
 46   begin
 47     i:=p[x];
 48     size[x]:=1;
 49     while i<>0 do
 50     begin
 51       y:=w[i].po;
 52       if fa[x]<>y then
 53       begin
 54         fa[y]:=x;
 55         d[y]:=d[x]+1;
 56         dfs1(y);
 57         size[x]:=size[x]+size[y];
 58       end;
 59       i:=w[i].next;
 60     end;
 61   end;
 62 
 63 procedure dfs2(x:longint);
 64   var i,y,q:longint;
 65   begin
 66     i:=p[x];
 67     inc(t);
 68     c[x]:=t;
 69     q:=0;
 70     while i<>0 do
 71     begin
 72       y:=w[i].po;
 73       if (c[y]=0) and (size[q]<size[y]) then q:=y;
 74       i:=w[i].next;
 75     end;
 76     if q<>0 then
 77     begin
 78       top[q]:=top[x];  //重儿子先访问
 79       dfs2(q);
 80     end;
 81     i:=p[x];  //然后访问轻儿子
 82     while i<>0 do
 83     begin
 84       y:=w[i].po;
 85       if c[y]=0 then
 86       begin
 87         top[y]:=y;
 88         dfs2(y);
 89       end;
 90       i:=w[i].next;
 91     end;
 92   end;
 93 
 94 procedure build(i,l,r:longint);
 95   var m:longint;
 96   begin
 97     if l=r then
 98     begin
 99       tree[i].sum:=b[l];
100       tree[i].max:=b[l];
101     end
102     else begin
103       m:=(l+r) shr 1;
104       build(i*2,l,m);
105       build(i*2+1,m+1,r);
106       update(i);
107     end;
108   end;
109 
110 procedure add(i,l,r:longint);
111   var m:longint;
112   begin
113     if l=r then
114     begin
115       tree[i].sum:=y;
116       tree[i].max:=y;
117     end
118     else begin
119       m:=(l+r) shr 1;
120       if x<=m then add(i*2,l,m) else add(i*2+1,m+1,r);
121       update(i);
122     end;
123   end;
124 
125 function getmax(i,l,r,x,y:longint):longint;
126   var m,t:longint;
127   begin
128     if (x<=l) and (y>=r) then exit(tree[i].max)
129     else begin
130       m:=(l+r) shr 1;
131       t:=-inf;
132       if x<=m then t:=max(t,getmax(i*2,l,m,x,y));
133       if y>m then t:=max(t,getmax(i*2+1,m+1,r,x,y));
134       exit(t);
135     end;
136   end;
137 
138 function getsum(i,l,r,x,y:longint):longint;
139   var m,t:longint;
140   begin
141     if (x<=l) and (y>=r) then exit(tree[i].sum)
142     else begin
143       m:=(l+r) shr 1;
144       t:=0;
145       if x<=m then t:=t+getsum(i*2,l,m,x,y);
146       if y>m then t:=t+getsum(i*2+1,m+1,r,x,y);
147       exit(t);
148     end;
149   end;
150 
151 function asksum(x,y:longint):longint;
152   var f1,f2:longint;
153   begin
154     asksum:=0;
155     f1:=top[x];
156     f2:=top[y];
157     while f1<>f2 do
158     begin
159       if d[f1]>=d[f2] then
160       begin
161         asksum:=asksum+getsum(1,1,n,c[f1],c[x]);
162         x:=fa[f1];
163       end
164       else begin
165         asksum:=asksum+getsum(1,1,n,c[f2],c[y]);
166         y:=fa[f2];
167       end;
168       f1:=top[x];
169       f2:=top[y];
170     end;
171     if c[x]>c[y] then swap(x,y);
172     asksum:=asksum+getsum(1,1,n,c[x],c[y]);
173   end;
174 
175 function askmax(x,y:longint):longint;
176   var f1,f2,t:longint;
177   begin
178     t:=-inf;
179     f1:=top[x];
180     f2:=top[y];
181     while f1<>f2 do  //提取
182     begin
183       if d[f1]>=d[f2] then
184       begin
185         t:=max(t,getmax(1,1,n,c[f1],c[x]));
186         x:=fa[f1];
187       end
188       else begin
189         t:=max(t,getmax(1,1,n,c[f2],c[y]));
190         y:=fa[f2];
191       end;
192       f1:=top[x];
193       f2:=top[y];
194     end;
195     if c[x]>c[y] then swap(x,y);
196     t:=max(t,getmax(1,1,n,c[x],c[y]));
197     exit(t);
198   end;
199 
200 begin
201   readln(n);
202   for i:=1 to n-1 do
203   begin
204     readln(x,y);
205     add(x,y);
206     add(y,x);
207   end;
208   d[1]:=1;
209   dfs1(1);
210   t:=0;
211   top[1]:=1;
212   dfs2(1);
213   for i:=1 to n do
214     read(b[c[i]]);
215   build(1,1,n);
216   readln(m);
217   for i:=1 to m do
218   begin
219     read(ch);
220     s:='';
221     while ch<>' ' do
222     begin
223       s:=s+ch;
224       read(ch);
225     end;
226     readln(x,y);
227     if s='QMAX' then
228       writeln(askmax(x,y))
229     else if s='QSUM' then
230       writeln(asksum(x,y))
231     else if s='CHANGE' then
232     begin
233       x:=c[x];
234       b[x]:=y;
235       add(1,1,n);
236     end;
237   end;
238 end.
View Code

 

posted on 2014-12-02 21:56  acphile  阅读(138)  评论(0编辑  收藏  举报