这是一道无比繁琐的题目
话说这道题使我第一次练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.