树链剖分在边上的应用
比维护点稍微麻烦一点,是对每条边标号,并且要记录每个点父亲边的编号和重儿子
然后注意各种细节
线段树上和bzoj1858的维护方法类似,覆盖的优先级高于加
具体见程序,完全是为了提升状态的练习

  1 type node=record
  2        po,next,num:longint;
  3      end;
  4 
  5 var son,a,d,fa,fp,f2,b,c,p,size,top:array[0..100010] of longint;
  6     w:array[0..200010] of node;
  7     tree,laz1,laz2:array[0..100010*4] of longint;
  8     x,y,z,i,n,t:longint;
  9     ch:char;
 10     s:string;
 11 
 12 function max(a,b:longint):longint;
 13   begin
 14     if a>b then exit(a) else exit(b);
 15   end;
 16 
 17 procedure add(x,y,c:longint);
 18   begin
 19     inc(t);
 20     w[t].po:=y;
 21     w[t].num:=c;
 22     w[t].next:=p[x];
 23     p[x]:=t;
 24   end;
 25 
 26 procedure swap(var a,b:longint);
 27   var c:longint;
 28   begin
 29     c:=a;
 30     a:=b;
 31     b:=c;
 32   end;
 33 
 34 procedure push(i:longint);
 35   begin
 36     if laz1[i]<>-1 then
 37     begin
 38       tree[i*2]:=laz1[i];
 39       tree[i*2+1]:=laz1[i];
 40       laz1[i*2]:=laz1[i];
 41       laz1[i*2+1]:=laz1[i];
 42       laz1[i]:=-1;
 43       laz2[i]:=0;
 44     end;
 45     if laz2[i]<>0 then
 46     begin
 47       inc(tree[i*2],laz2[i]);
 48       inc(tree[i*2+1],laz2[i]);
 49       if laz1[i*2]<>-1 then inc(laz1[i*2],laz2[i])
 50       else inc(laz2[i*2],laz2[i]);
 51       if laz1[i*2+1]<>-1 then inc(laz1[i*2+1],laz2[i])
 52       else inc(laz2[i*2+1],laz2[i]);
 53       laz2[i]:=0;
 54     end;
 55   end;
 56 
 57 procedure dfs1(x:longint);
 58   var i,y:longint;
 59   begin
 60     i:=p[x];
 61     size[x]:=1;
 62     while i<>0 do
 63     begin
 64       y:=w[i].po;
 65       if fa[x]<>y then
 66       begin
 67         fp[y]:=w[i].num;
 68         fa[y]:=x;
 69         d[y]:=d[x]+1;
 70         dfs1(y);
 71         size[x]:=size[x]+size[y];
 72       end;
 73       i:=w[i].next;
 74     end;
 75   end;
 76 
 77 procedure dfs2(x:longint);
 78   var i,y,q:longint;
 79   begin
 80     i:=p[x];
 81     q:=0;
 82     while i<>0 do
 83     begin
 84       if fa[w[i].po]=x then
 85         if size[w[q].po]<size[w[i].po] then q:=i;
 86       i:=w[i].next;
 87     end;
 88     if q=0 then exit;
 89     top[w[q].po]:=top[x];
 90     son[x]:=w[q].num;
 91     inc(t);
 92     c[t]:=w[q].num;
 93     b[w[q].num]:=t;
 94     dfs2(w[q].po);
 95     i:=p[x];
 96     while i<>0 do
 97     begin
 98       y:=w[i].po;
 99       if (i<>q) and (fa[y]=x) then
100       begin
101         inc(t);
102         c[t]:=w[i].num;
103         b[w[i].num]:=t;
104         top[y]:=y;
105         dfs2(y);
106       end;
107       i:=w[i].next;
108     end;
109   end;
110 
111 procedure build(i,l,r:longint);
112   var m:longint;
113   begin
114     laz1[i]:=-1;
115     laz2[i]:=0;
116     if l=r then tree[i]:=a[c[l]]
117     else begin
118       m:=(l+r) shr 1;
119       build(i*2,l,m);
120       build(i*2+1,m+1,r);
121       tree[i]:=max(tree[i*2],tree[i*2+1]);
122     end;
123   end;
124 
125 procedure change(i,l,r,x,y,z:longint);
126   var m:longint;
127   begin
128     if x>y then exit;
129     if (x<=l) and (y>=r) then
130     begin
131       laz1[i]:=z;
132       tree[i]:=z;
133       laz2[i]:=0;
134     end
135     else begin
136       push(i);
137       m:=(l+r) shr 1;
138       if x<=m then change(i*2,l,m,x,y,z);
139       if y>m then change(i*2+1,m+1,r,x,y,z);
140       tree[i]:=max(tree[i*2],tree[i*2+1]);
141     end;
142   end;
143 
144 procedure fadd(i,l,r,x,y:longint);
145   var m:longint;
146   begin
147     if x>y then exit;
148     if (x<=l) and (y>=r) then
149     begin
150       if laz1[i]<>-1 then inc(laz1[i],z)
151       else inc(laz2[i],z);
152       inc(tree[i],z);
153     end
154     else begin
155       push(i);
156       m:=(l+r) shr 1;
157       if x<=m then fadd(i*2,l,m,x,y);
158       if y>m then fadd(i*2+1,m+1,r,x,y);
159       tree[i]:=max(tree[i*2],tree[i*2+1]);
160     end;
161   end;
162 
163 function getans(i,l,r,x,y:longint):longint;
164   var m,s:longint;
165   begin
166     if x>y then exit(0);
167     if (x<=l) and (y>=r) then exit(tree[i])
168     else begin
169       push(i);
170       m:=(l+r) shr 1;
171       s:=0;
172       if x<=m then s:=getans(i*2,l,m,x,y);
173       if y>m then s:=max(s,getans(i*2+1,m+1,r,x,y));
174       exit(s);
175     end;
176   end;
177 
178 procedure cover(x,y:longint);
179   var f1,f2:longint;
180   begin
181     f1:=top[x];
182     f2:=top[y];
183     while f1<>f2 do
184     begin
185       if d[f1]>=d[f2] then
186       begin
187         change(1,1,n-1,b[fp[f1]],b[fp[x]],z);
188         x:=fa[f1];
189       end
190       else begin
191         change(1,1,n-1,b[fp[f2]],b[fp[y]],z);
192         y:=fa[f2];
193       end;
194       f1:=top[x];
195       f2:=top[y];
196     end;
197     if x=y then exit
198     else if b[fp[x]]>b[fp[y]] then swap(x,y);
199     change(1,1,n-1,b[son[x]],b[fp[y]],z);
200   end;
201 
202 procedure add(x,y:longint);
203   var f1,f2:longint;
204   begin
205     f1:=top[x];
206     f2:=top[y];
207     while f1<>f2 do
208     begin
209       if d[f1]>=d[f2] then
210       begin
211         fadd(1,1,n-1,b[fp[f1]],b[fp[x]]);
212         x:=fa[f1];
213       end
214       else begin
215         fadd(1,1,n-1,b[fp[f2]],b[fp[y]]);
216         y:=fa[f2];
217       end;
218       f1:=top[x];
219       f2:=top[y];
220     end;
221     if x=y then exit
222     else if b[fp[x]]>b[fp[y]] then swap(x,y);
223     fadd(1,1,n-1,b[son[x]],b[fp[y]]);
224   end;
225 
226 function ask(x,y:longint):longint;
227   var s,f1,f2:longint;
228   begin
229     s:=0;
230     f1:=top[x];
231     f2:=top[y];
232     while f1<>f2 do
233     begin
234       if d[f1]>=d[f2] then
235       begin
236         s:=max(s,getans(1,1,n-1,b[fp[f1]],b[fp[x]]));
237         x:=fa[f1];
238       end
239       else begin
240         s:=max(s,getans(1,1,n-1,b[fp[f2]],b[fp[y]]));
241         y:=fa[f2];
242       end;
243       f1:=top[x];
244       f2:=top[y];
245     end;
246     if x=y then exit(s)
247     else if b[fp[x]]>b[fp[y]] then swap(x,y);
248     s:=max(s,getans(1,1,n-1,b[son[x]],b[fp[y]]));
249     exit(s);
250   end;
251 
252 begin
253   readln(n);
254   for i:=1 to n-1 do
255   begin
256     readln(x,y,a[i]);
257     add(x,y,i);
258     add(y,x,i);
259   end;
260   t:=0;
261   dfs1(1);
262   top[1]:=1;
263   dfs2(1);
264   while true do
265   begin
266     read(ch);
267     s:='';
268     while ch<>' ' do
269     begin
270       s:=s+ch;
271       if s='Stop' then halt;
272       read(ch);
273     end;
274     read(x,y);
275     if s='Max' then
276       writeln(ask(x,y))
277     else if s='Change' then
278       change(1,1,n-1,b[x],b[x],y)
279     else if s='Cover' then
280     begin
281       read(z);
282       cover(x,y);
283     end
284     else if s='Add' then
285     begin
286       read(z);
287       add(x,y);
288     end;
289     readln;
290   end;
291 end.
View Code

 

posted on 2015-01-31 23:27  acphile  阅读(194)  评论(0编辑  收藏  举报