6779. Can you answer these queries VII - SPOJ

Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ).

You have to apply Q ( Q<=100000 ) operations:

1. 1 a b : answer the maximum contiguous sum (maybe empty,will always larger than or equal to 0 ) from the path a->b ( inclusive ).

2. 2 a b c : change all value in the path a->b ( inclusive ) to c.
Input

first line consists one interger N.

next line consists N interger x_i.

next N-1 line , each consists two interger u,v , means that node u and node v are connected

next line consists 1 interger Q.

next Q line : 1 a b or 2 a b c .
Output

For each query, output one line the maximum contiguous sum.
Example

Input:
5

-3 -2 1 2 3

1 2

2 3

1 4

4 5

3

1 2 5

2 3 4 2

1 2 5

Output:
5

9

 

GSS系列最后一道题终于攻破

树链剖分可做,不过代码很长,280行.....

酝酿了这么久终于写了,以前一直不敢做,今天觉得是时候了

又认真看了一遍入门http://blog.sina.com.cn/s/blog_7a1746820100wp67.html

用了一个下午的时间把它AC了,觉得很欣慰,竟然是一次AC,幸福来得太突然.....

 

  1 const
  2     inf=-maxlongint;
  3 type
  4     node=record
  5       lson,rson,left,right,lmax,rmax,amax,lazy,sum:longint;
  6     end;
  7 
  8 var
  9     tree:array[0..200010]of node;
 10     first,next,last:array[0..200010]of longint;
 11     son,fa,size,dep,w,top,root,a:array[0..100010]of longint;
 12     flag:array[0..100010]of boolean;
 13     tot,n,num,ll,rr:longint;
 14 
 15 function max(x,y:longint):longint;
 16 begin
 17     if x>y then exit(x);
 18     exit(y);
 19 end;
 20 
 21 procedure swap(var x,y:longint);
 22 var
 23     t:longint;
 24 begin
 25     t:=x;x:=y;y:=t;
 26 end;
 27 
 28 procedure insert(x,y:longint);
 29 begin
 30     inc(num);
 31     last[num]:=y;
 32     next[num]:=first[x];
 33     first[x]:=num;
 34 end;
 35 
 36 procedure dfs1(x,d,f:longint);
 37 var
 38     i,j:longint;
 39 begin
 40     fa[x]:=f;
 41     flag[x]:=true;
 42     dep[x]:=d;
 43     size[x]:=1;
 44     i:=first[x];
 45     j:=0;
 46     while i<>0 do
 47       begin
 48         if flag[last[i]]=false then
 49         begin
 50           dfs1(last[i],d+1,x);
 51           inc(size[x],size[last[i]]);
 52           if size[last[i]]>size[j] then j:=last[i];
 53         end;
 54         i:=next[i];
 55       end;
 56     son[x]:=j;
 57 end;
 58 
 59 procedure build(l,r:longint);
 60 var
 61     now,mid:longint;
 62 begin
 63     inc(tot);
 64     now:=tot;
 65     with tree[now] do
 66       begin
 67         left:=l;
 68         right:=r;
 69         lazy:=inf;
 70       end;
 71     if l=r then exit;
 72     mid:=(l+r)>>1;
 73     with tree[now] do
 74       begin
 75         lson:=tot+1;
 76         build(l,mid);
 77         rson:=tot+1;
 78         build(mid+1,r);
 79       end;
 80 end;
 81 
 82 procedure new(x,now:longint);
 83 begin
 84     with tree[now] do
 85       begin
 86         if left<>right then lazy:=x;
 87         sum:=x*(right-left+1);
 88         amax:=max(0,sum);
 89         lmax:=amax;
 90         rmax:=amax;
 91       end;
 92 end;
 93 
 94 procedure down(now:longint);
 95 begin
 96     with tree[now] do
 97       begin
 98         new(lazy,lson);
 99         new(lazy,rson);
100         lazy:=inf;
101       end;
102 end;
103 
104 procedure up(now:longint);
105 begin
106     with tree[now] do
107       begin
108         sum:=tree[lson].sum+tree[rson].sum;
109         amax:=max(max(tree[lson].amax,tree[rson].amax),tree[lson].rmax+tree[rson].lmax);
110         lmax:=max(tree[lson].lmax,tree[lson].sum+tree[rson].lmax);
111         rmax:=max(tree[rson].rmax,tree[rson].sum+tree[lson].rmax);
112       end;
113 end;
114 
115 procedure change(x,now:longint);
116 var
117     mid:longint;
118 begin
119     with tree[now] do
120       begin
121         if(ll<=left)and(rr>=right) then
122         begin
123           new(x,now);
124           exit;
125         end;
126         if lazy<>inf then down(now);
127         mid:=(left+right)>>1;
128         if rr>mid then change(x,rson);
129         if ll<=mid then change(x,lson);
130         up(now);
131       end;
132 end;
133 
134 procedure dfs2(x,t,ww:longint);
135 var
136     i:longint;
137 begin
138     flag[x]:=false;
139     top[x]:=t;
140     w[x]:=ww;
141     if son[x]=0 then
142     begin
143       root[x]:=tot+1;
144       build(1,ww);
145       ll:=ww;
146       rr:=ww;
147       change(a[x],root[x]);
148       exit;
149     end;
150     dfs2(son[x],t,ww+1);
151     root[x]:=root[son[x]];
152     ll:=ww;
153     rr:=ww;
154     change(a[x],root[x]);
155     i:=first[x];
156     while i<>0 do
157       begin
158         if flag[last[i]] then dfs2(last[i],last[i],1);
159         i:=next[i];
160       end;
161 end;
162 
163 procedure init;
164 var
165     i,x,y:longint;
166 begin
167     read(n);
168     for i:=1 to n do
169       read(a[i]);
170     for i:=1 to n-1 do
171       begin
172         read(x,y);
173         insert(x,y);
174         insert(y,x);
175       end;
176     dfs1(1,1,0);
177     dfs2(1,1,1);
178 end;
179 
180 procedure get(var am,lm,rm,su:longint;now:longint);
181 var
182     mid:longint;
183 begin
184     with tree[now] do
185       begin
186         if lazy<>inf then down(now);
187         if(ll<=left)and(rr>=right) then
188         begin
189           am:=max(max(am,amax),lm+rmax);
190           lm:=max(lmax,sum+lm);
191           rm:=max(rm,su+rmax);
192           su:=su+sum;
193           exit;
194         end;
195         mid:=(left+right)>>1;
196         if rr>mid then get(am,lm,rm,su,rson);
197         if ll<=mid then get(am,lm,rm,su,lson);
198       end;
199 end;
200 
201 procedure work1;
202 var
203     x,y,amax1,lmax1,rmax1,sum1,amax2,lmax2,rmax2,sum2:longint;
204 begin
205     read(x,y);
206     amax1:=0;
207     lmax1:=0;
208     rmax1:=0;
209     sum1:=0;
210     amax2:=0;
211     lmax2:=0;
212     rmax2:=0;
213     sum2:=0;
214     if dep[top[x]]<dep[top[y]] then swap(x,y);
215     while top[x]<>top[y] do
216       begin
217         ll:=1;
218         rr:=w[x];
219         get(amax1,lmax1,rmax1,sum1,root[x]);
220         x:=fa[top[x]];
221         if dep[top[x]]<dep[top[y]] then
222         begin
223           swap(x,y);
224           swap(amax1,amax2);
225           swap(lmax1,lmax2);
226           swap(rmax1,rmax2);
227           swap(sum1,sum2);
228         end;
229       end;
230     if dep[x]<dep[y] then
231     begin
232       swap(x,y);
233       swap(amax1,amax2);
234       swap(lmax1,lmax2);
235       swap(rmax1,rmax2);
236       swap(sum1,sum2);
237     end;
238     ll:=w[y];
239     rr:=w[x];
240     get(amax1,lmax1,rmax1,sum1,root[x]);
241     writeln(max(max(amax1,amax2),lmax1+lmax2));
242 end;
243 
244 procedure work2;
245 var
246     x,y,z:longint;
247 begin
248     read(x,y,z);
249     if dep[top[x]]<dep[top[y]] then swap(x,y);
250     while top[x]<>top[y] do
251       begin
252         ll:=1;
253         rr:=w[x];
254         change(z,root[x]);
255         x:=fa[top[x]];
256         if dep[top[x]]<dep[top[y]] then swap(x,y);
257       end;
258     if dep[x]<dep[y] then swap(x,y);
259     ll:=w[y];
260     rr:=w[x];
261     change(z,root[x]);
262 end;
263 
264 procedure work;
265 var
266     i,q,s:longint;
267 begin
268     read(q);
269     for i:=1 to q do
270       begin
271         read(s);
272         if s=1 then work1
273         else work2;
274       end;
275 end;
276 
277 begin
278     init;
279     work;
280 end.
View Code

 

posted @ 2014-03-14 17:14  Randolph87  阅读(396)  评论(1编辑  收藏  举报