题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作:
1:将X号点的点权修改为Y
2:查询X到Y的路径上第K大的点权
n,q<=80000 a[i]<=10^8
思路:此题明显地体现了我对主席树理解不深
树上路径K大可以直接用树剖+二分答案+树做
但DFS序+主席树也可以
对于点U,它能影响DFS序上的区间(st[u],ed[u])
所以维护方法就是类似序列K大一样 s[st[u]]++ s[ed[u]+1]--
对于路径(x,y),信息为s[x]+s[y]-s[lca(x,y)]-s[fa[lca(x,y)]]
但因为是在树上的操作,所以每个点是从它在树上的父亲继承下来的,并不是DFS序上的前一个继承的
所以在DFS时就可以建立一棵没有修改过的原树
对于询问,再建立一棵树只做更改,询问时加上原树的信息即可
不开两棵树可以,不过需要主席树合并
1 var t:array[0..8000000]of record 2 l,r,s:longint; 3 end; 4 f:array[0..210000,0..18]of longint; 5 head,vet,next,st,ed,dep,flag,hash,root1,root2,b:array[0..210000]of longint; 6 d:array[0..210000,1..3]of longint; 7 a:array[0..210000]of longint; 8 q1,q2:array[0..80000]of longint; 9 n,m,i,j,tot,time,up,la,lb,cnt,q,x,y,tmp,p,sum,z,f1,f2,f3,f4:longint; 10 11 procedure add(a,b:longint); 12 begin 13 inc(tot); 14 next[tot]:=head[a]; 15 vet[tot]:=b; 16 head[a]:=tot; 17 end; 18 19 function max(x,y:longint):longint; 20 begin 21 if x>y then exit(x); 22 exit(y); 23 end; 24 25 procedure swap(var x,y:longint); 26 var t:longint; 27 begin 28 t:=x; x:=y; y:=t; 29 end; 30 31 function find(x:longint):longint; 32 var l,r,mid:longint; 33 begin 34 l:=1; r:=up; 35 while l<=r do 36 begin 37 mid:=(l+r)>>1; 38 if hash[mid]=x then exit(mid); 39 if hash[mid]<x then l:=mid+1 40 else r:=mid-1; 41 end; 42 end; 43 44 procedure update(l,r:longint;var p:longint;v,x:longint); 45 var mid:longint; 46 begin 47 inc(cnt); t[cnt]:=t[p]; 48 p:=cnt; t[p].s:=t[p].s+x; 49 if l=r then exit; 50 mid:=(l+r)>>1; 51 if v<=mid then update(l,mid,t[p].l,v,x) 52 else update(mid+1,r,t[p].r,v,x); 53 end; 54 55 procedure dfs(u:longint); 56 var e,v,i,tmp:longint; 57 begin 58 for i:=1 to 18 do 59 begin 60 if dep[u]<(1<<i) then break; 61 f[u,i]:=f[f[u,i-1],i-1]; 62 end; 63 tmp:=find(a[u]); 64 root1[u]:=root1[f[u,0]]; 65 update(1,up,root1[u],tmp,1); 66 inc(time); st[u]:=time; ed[u]:=time; 67 flag[u]:=1; 68 e:=head[u]; 69 while e<>0 do 70 begin 71 v:=vet[e]; 72 if flag[v]=0 then 73 begin 74 f[v,0]:=u; 75 dep[v]:=dep[u]+1; 76 dfs(v); 77 ed[u]:=max(ed[u],ed[v]); 78 end; 79 e:=next[e]; 80 end; 81 end; 82 83 function lca(x,y:longint):longint; 84 var d,i:longint; 85 begin 86 if dep[x]<dep[y] then swap(x,y); 87 d:=dep[x]-dep[y]; 88 for i:=0 to 18 do 89 if d and (1<<i)>0 then x:=f[x,i]; 90 for i:=18 downto 0 do 91 if f[x,i]<>f[y,i] then 92 begin 93 x:=f[x,i]; y:=f[y,i]; 94 end; 95 if x=y then exit(x); 96 exit(f[x,0]); 97 end; 98 99 procedure qsort(l,r:longint); 100 var i,j,mid:longint; 101 begin 102 i:=l; j:=r; mid:=b[(l+r)>>1]; 103 repeat 104 while mid>b[i] do inc(i); 105 while mid<b[j] do dec(j); 106 if i<=j then 107 begin 108 swap(b[i],b[j]); 109 inc(i); dec(j); 110 end; 111 until i>j; 112 if l<j then qsort(l,j); 113 if i<r then qsort(i,r); 114 end; 115 116 function lowbit(x:longint):longint; 117 begin 118 exit(x and (-x)); 119 end; 120 121 function query(l,r,k:longint):longint; 122 var s1,s2,i,mid:longint; 123 begin 124 if l=r then exit(l); 125 mid:=(l+r)>>1; 126 s1:=0; s2:=0; 127 for i:=1 to la do s1:=s1+t[t[q1[i]].l].s; 128 for i:=1 to lb do s2:=s2+t[t[q2[i]].l].s; 129 s2:=s2+t[t[f1].l].s+t[t[f2].l].s; 130 s1:=s1+t[t[f3].l].s+t[t[f4].l].s; 131 if s2-s1>=k then 132 begin 133 f1:=t[f1].l; f2:=t[f2].l; 134 f3:=t[f3].l; f4:=t[f4].l; 135 for i:=1 to la do q1[i]:=t[q1[i]].l; 136 for i:=1 to lb do q2[i]:=t[q2[i]].l; 137 exit(query(l,mid,k)); 138 end 139 else 140 begin 141 f1:=t[f1].r; f2:=t[f2].r; 142 f3:=t[f3].r; f4:=t[f4].r; 143 for i:=1 to la do q1[i]:=t[q1[i]].r; 144 for i:=1 to lb do q2[i]:=t[q2[i]].r; 145 exit(query(mid+1,r,k-(s2-s1))); 146 end; 147 end; 148 149 begin 150 assign(input,'data.in'); reset(input); 151 assign(output,'tyvj2133.out'); rewrite(output); 152 read(n,m); 153 for i:=1 to n do 154 begin 155 read(a[i]); b[i]:=a[i]; 156 end; 157 q:=n; 158 for i:=1 to n-1 do 159 begin 160 read(x,y); 161 add(x,y); 162 add(y,x); 163 end; 164 165 for i:=1 to m do 166 for j:=1 to 3 do read(d[i,j]); 167 for i:=1 to m do 168 if d[i,1]=0 then 169 begin 170 inc(q); b[q]:=d[i,3]; 171 end; 172 qsort(1,q); 173 hash[1]:=b[1]; up:=1; 174 for i:=2 to q do 175 if b[i]<>b[i-1] then begin inc(up); hash[up]:=b[i]; end; 176 dfs(1); 177 178 179 for i:=1 to m do 180 if d[i,1]=0 then 181 begin 182 tmp:=find(a[d[i,2]]); 183 j:=st[d[i,2]]; 184 while j<=n do 185 begin 186 update(1,up,root2[j],tmp,-1); 187 j:=j+lowbit(j); 188 end; 189 j:=ed[d[i,2]]+1; 190 while j<=n do 191 begin 192 update(1,up,root2[j],tmp,1); 193 j:=j+lowbit(j); 194 end; 195 tmp:=find(d[i,3]); 196 j:=st[d[i,2]]; 197 while j<=n do 198 begin 199 update(1,up,root2[j],tmp,1); 200 j:=j+lowbit(j); 201 end; 202 j:=ed[d[i,2]]+1; 203 while j<=n do 204 begin 205 update(1,up,root2[j],tmp,-1); 206 j:=j+lowbit(j); 207 end; 208 209 a[d[i,2]]:=d[i,3]; 210 end 211 else 212 begin 213 la:=0; lb:=0; p:=lca(d[i,2],d[i,3]); 214 j:=st[d[i,2]]; 215 while j>0 do 216 begin 217 inc(lb); q2[lb]:=root2[j]; 218 j:=j-lowbit(j); 219 end; 220 221 j:=st[d[i,3]]; 222 while j>0 do 223 begin 224 inc(lb); q2[lb]:=root2[j]; 225 j:=j-lowbit(j); 226 end; 227 228 j:=st[p]; 229 while j>0 do 230 begin 231 inc(la); q1[la]:=root2[j]; 232 j:=j-lowbit(j); 233 end; 234 235 j:=st[f[p,0]]; 236 while j>0 do 237 begin 238 inc(la); q1[la]:=root2[j]; 239 j:=j-lowbit(j); 240 end; 241 242 f1:=root1[d[i,2]]; f2:=root1[d[i,3]]; 243 f3:=root1[p]; f4:=root1[f[p,0]]; 244 sum:=dep[d[i,2]]+dep[d[i,3]]-dep[p]*2+1; 245 z:=sum-d[i,1]+1; 246 if sum<d[i,1] then writeln('invalid request!') 247 else writeln(hash[query(1,up,z)]); 248 end; 249 250 251 close(input); 252 close(output); 253 end.