这是一道无比繁琐的题目
话说这道题使我第一次练dfs序,比较感动;
首先dfs序就是在dfs过程中按照访问的顺序给每个点标上两个“时间戳”
一个是第一次访问到点i时的时间戳c[i],一个是访问完以i为根时的时间戳cc[i]
根据c[i],我们就可以将树变成序列,并且以i为根的子树,是序列上连续的一段
当进行单点修改时,我们可以用树状数组前缀和维护树上的点到根路径上所有点的修改情况和;
比如当点i修改时(比如+1) 则w[c[i]]+1,w[cc[i]]-1
然后这道题显然是要在dfs序上套带修改的主席树,根据bzoj2588的经验我们很好解决这个问题
由于修改的点要离散化,已经离线了,干脆用lca-tarjan求lca好了
由于空间卡的比较严,所以我们不能直接树状数组+主席树
而要先把原树建成主席树,然后修改的时候新建一棵主席树,用树状数组+主席树解决

  1 const maxn=80001;
  2 
  3 type node=record
  4        po,next:longint;
  5      end;
  6      link=record
  7        l,r,s:longint;
  8      end;
  9      point=record
 10        x,y,z:longint;
 11      end;
 12      qu=record
 13        num,loc,next:longint;
 14      end;
 15 
 16 
 17 var tree:array[0..10000010] of link;
 18     q:array[0..80010] of point;
 19     w:array[0..160010] of node;
 20     que:array[0..160010] of qu;
 21     v:array[0..80010] of boolean;
 22     e:array[0..4] of longint;
 23     g,fa,an,loc,d1,d2,ph,h,cc,c,b:array[0..80010] of longint;
 24     st:array[0..80010,0..4] of longint;
 25     sa,a:array[0..160010] of longint;
 26     j,k,t,tot,num,len,x,y,z,i,p,s,n,m:longint;
 27 
 28 function lowbit(x:longint):longint;
 29   begin
 30     exit(x and (-x));
 31   end;
 32 
 33 procedure update(x:longint);
 34   begin
 35     tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s;
 36   end;
 37 
 38 procedure add(x,y:longint);
 39   begin
 40     inc(len);
 41     w[len].po:=y;
 42     w[len].next:=d1[x];
 43     d1[x]:=len;
 44   end;
 45 
 46 procedure addq(x,y,z:longint);
 47   begin
 48     inc(num);
 49     que[num].num:=y;
 50     que[num].loc:=z;
 51     que[num].next:=d2[x];
 52     d2[x]:=num;
 53   end;
 54 
 55 function find(x:longint):longint;
 56   var l,r,m:longint;
 57   begin
 58     l:=1;
 59     r:=p;
 60     while l<=r do
 61     begin
 62       m:=(l+r) shr 1;
 63       if sa[m]=x then exit(m);
 64       if sa[m]>x then r:=m-1 else l:=m+1;
 65     end;
 66   end;
 67 
 68 function getf(x:longint):longint;
 69   begin
 70     if a[x]<>x then a[x]:=getf(a[x]);
 71     exit(a[x]);
 72   end;
 73 
 74 procedure dfs(x:longint);
 75   var i,y:longint;
 76   begin
 77     i:=d1[x];
 78     v[x]:=true;
 79     inc(tot);
 80     b[tot]:=x;  //b表示序列上的点对应的树上的哪个点
 81     c[x]:=tot;
 82     while i<>0 do
 83     begin
 84       y:=w[i].po;
 85       if not v[y] then
 86       begin
 87         fa[y]:=x;
 88         dfs(y);
 89         a[y]:=x;
 90       end;
 91       i:=w[i].next;
 92     end;
 93     cc[x]:=tot;
 94     i:=d2[x];
 95     while i<>0 do
 96     begin
 97       y:=que[i].num;
 98       if v[y] and (an[que[i].loc]=0) then  //lca-tarjan
 99         an[que[i].loc]:=getf(y);
100       i:=que[i].next;
101     end;
102   end;
103 
104 procedure sort(l,r: longint);
105   var i,j,x,y: longint;
106   begin
107     i:=l;
108     j:=r;
109     x:=a[(l+r) div 2];
110     repeat
111       while a[i]<x do inc(i);
112       while x<a[j] do dec(j);
113       if not(i>j) then
114       begin
115         y:=a[i];
116         a[i]:=a[j];
117         a[j]:=y;
118         inc(i);
119         j:=j-1;
120       end;
121     until i>j;
122     if l<j then sort(l,j);
123     if i<r then sort(i,r);
124   end;
125 
126 function build(l,r:longint):longint;
127   var m,q:longint;
128   begin
129     inc(t);
130     if l=r then exit(t)
131     else begin
132       q:=t;
133       m:=(l+r) shr 1;
134       tree[q].l:=build(l,m);
135       tree[q].r:=build(m+1,r);
136       exit(q);
137     end;
138   end;
139 
140 function insert(last,x,l,r,z:longint):longint;
141   var m,q:longint;
142   begin
143     inc(t);
144     if l=r then
145     begin
146       tree[t].s:=tree[last].s+z;
147       exit(t);
148     end
149     else begin
150       m:=(l+r) shr 1;
151       q:=t;
152       if x<=m then
153       begin
154         tree[q].r:=tree[last].r;
155         last:=tree[last].l;
156         tree[q].l:=insert(last,x,l,m,z);
157       end
158       else begin
159         tree[q].l:=tree[last].l;
160         last:=tree[last].r;
161         tree[q].r:=insert(last,x,m+1,r,z);
162       end;
163       update(q);
164       exit(q);
165     end;
166   end;
167 
168 procedure work(i,x,z:longint);
169   begin
170     while i<=n do  //树状数组+主席树
171     begin
172       h[i]:=insert(h[i],x,1,p,z);  
173       i:=i+lowbit(i);
174     end;
175   end;
176 
177 procedure get(x,y:longint);
178   var i:longint;
179   begin
180     e[y]:=1;
181     st[1,y]:=ph[x];
182     i:=x;
183     while i>0 do
184     begin
185       if h[i]<>0 then
186       begin
187         inc(e[y]);
188         st[e[y],y]:=h[i];
189       end;
190       i:=i-lowbit(i);
191     end;
192   end;
193 
194 function sum:longint;
195   var i,j:longint;
196   begin
197     sum:=0;
198     for j:=1 to 4 do
199       for i:=1 to e[j] do
200         if (j<=2) then
201           sum:=sum+tree[tree[st[i,j]].r].s
202         else sum:=sum-tree[tree[st[i,j]].r].s;//u,v路径上的情况为tree[u]+tree[v]-tree[lca(u,v)]-tree[fa[lca(u,v)]];
203   end;
204 
205 function getans(l,r,k:longint):longint;
206   var m,s,i,j:longint;
207   begin
208     if l=r then exit(sa[l])
209     else begin
210       m:=(l+r) shr 1;
211       s:=sum;
212       if s>=k then
213       begin
214         for j:=1 to 4 do
215           for i:=1 to e[j] do
216             st[i,j]:=tree[st[i,j]].r;
217         exit(getans(m+1,r,k));
218       end
219       else begin
220         k:=k-s;
221         for j:=1 to 4 do
222           for i:=1 to e[j] do
223             st[i,j]:=tree[st[i,j]].l;
224         exit(getans(l,m,k));
225       end;
226     end;
227   end;
228 
229 begin
230   readln(n,m);
231   for i:=1 to n do
232   begin
233     read(g[i]);
234     a[i]:=g[i];
235   end;
236   s:=n;
237   for i:=1 to n-1 do
238   begin
239     readln(x,y);
240     add(x,y);
241     add(y,x);
242   end;
243 
244   for i:=1 to m do
245   begin
246     readln(q[i].z,q[i].x,q[i].y);
247     if q[i].z=0 then
248     begin
249       inc(s);
250       a[s]:=q[i].y;
251     end
252     else begin
253       addq(q[i].x,q[i].y,i);
254       addq(q[i].y,q[i].x,i);
255     end;
256   end;
257   sort(1,s);
258   p:=1;
259   sa[1]:=a[1];
260   for i:=2 to s do
261     if a[i]<>a[i-1] then  //离散化
262     begin
263       inc(p);
264       sa[p]:=a[i];
265     end;
266 
267   for i:=1 to n do
268     a[i]:=i;
269   dfs(1);
270   t:=0;
271   h[0]:=build(1,p);
272   ph[0]:=h[0];
273   for i:=1 to n do
274   begin
275     loc[i]:=find(g[b[i]]);
276     y:=fa[b[i]];
277     ph[i]:=insert(ph[c[y]],loc[i],1,p,1);  //建立未修改前的主席树
278   end;
279   for i:=1 to m do
280   begin
281     if q[i].z<>0 then
282     begin
283       z:=an[i];
284       get(c[q[i].x],1);  //提取区间
285       get(c[q[i].y],2);
286       get(c[z],3);
287       get(c[fa[z]],4);
288       s:=0;
289       for j:=1 to 4 do
290       begin
291         for k:=1 to e[j] do
292           if (j<=2) then
293             s:=s+tree[st[k,j]].s
294           else s:=s-tree[st[k,j]].s;
295       end;
296       if s<q[i].z then writeln('invalid request!')
297       else writeln(getans(1,p,q[i].z));
298     end
299     else begin
300       x:=q[i].x;
301       work(c[x],loc[c[x]],-1);
302       work(cc[x]+1,loc[c[x]],1);
303       loc[c[x]]:=find(q[i].y);
304       work(c[x],loc[c[x]],1);
305       work(cc[x]+1,loc[c[x]],-1);
306     end;
307   end;
308 end.
View Code

 

posted on 2014-12-03 22:55  acphile  阅读(139)  评论(0编辑  收藏  举报