肯定是树链剖分+线段树,关键是怎么维护

绝对值和这个东西显然不能简单的合并标记

因为对于负数,加之后绝对值和是变小的

那我们考虑对负数和非负数数分别维护

下面的问题就是经过操作如果负数变成了正数怎么办

注意每次加的都是正数,这意味着这样的变化最多发生n次,

每个数发生这种变化,我们就用push到底即可,这样最多nlogn的

所以我们只要在维护一个区间最大负数即可

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

 

posted on 2015-07-21 20:04  acphile  阅读(222)  评论(0编辑  收藏  举报