首先肯定是主席树
但这是一类“动态树”,似乎没有什么好的办法
那就暴力呗,这里用到启发式合并,即两棵树合并,重建节点少的的那棵
可以用并查集维护连通性
查询主席树的建立还是和bzoj2588一样
1 const maxn=80010; 2 type node=record 3 po,next:longint; 4 end; 5 point=record 6 l,r,s:longint; 7 end; 8 9 var tree:array[0..maxn*200] of point; 10 w:array[0..2*maxn] of node; 11 size,fs,h,p,c,a,q1,q2,rank,sa,fa,d:array[0..maxn] of longint; 12 anc:array[0..maxn,0..20] of longint; 13 u,e,testcase,j,t,z,i,n,m,k,x,y,len,ans,s:longint; 14 ch:char; 15 16 procedure swap(var a,b:longint); 17 var c:longint; 18 begin 19 c:=a; 20 a:=b; 21 b:=c; 22 end; 23 24 function getf(x:longint):longint; 25 begin 26 if fs[x]<>x then fs[x]:=getf(fs[x]); 27 exit(fs[x]); 28 end; 29 30 procedure update(i:longint); 31 begin 32 tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s; 33 end; 34 35 procedure addedge(x,y:longint); 36 begin 37 inc(len); 38 w[len].po:=y; 39 w[len].next:=p[x]; 40 p[x]:=len; 41 end; 42 43 procedure union; 44 var k1,k2:longint; 45 begin 46 k1:=getf(x); 47 k2:=getf(y); 48 if k1<>k2 then 49 begin 50 if size[k1]<size[k2] then swap(x,y); //启发式合并 51 if size[k1]>=size[k2] then 52 begin 53 size[k1]:=size[k1]+size[k2]; 54 fs[k2]:=k1; 55 end 56 else begin 57 size[k2]:=size[k2]+size[k1]; 58 fs[k1]:=k2; 59 end; 60 end; 61 end; 62 63 procedure sort(l,r: longint); 64 var i,j,x:longint; 65 begin 66 i:=l; 67 j:=r; 68 x:=a[(l+r) div 2]; 69 repeat 70 while (a[i]<x) do inc(i); 71 while (x<a[j]) do dec(j); 72 if not(i>j) then 73 begin 74 swap(a[i],a[j]); 75 swap(c[i],c[j]); 76 inc(i); 77 j:=j-1; 78 end; 79 until i>j; 80 if l<j then sort(l,j); 81 if i<r then sort(i,r); 82 end; 83 84 function build(l,r:longint):longint; 85 var q,m:longint; 86 begin 87 inc(t); 88 if l=r then exit(t) 89 else begin 90 q:=t; 91 m:=(l+r) shr 1; 92 tree[q].l:=build(l,m); 93 tree[q].r:=build(m+1,r); 94 exit(q); 95 end; 96 end; 97 98 function add(last,l,r,x:longint):longint; 99 var q,m:longint; 100 begin 101 inc(t); 102 if l=r then 103 begin 104 tree[t].s:=tree[last].s+1; 105 exit(t); 106 end 107 else begin 108 q:=t; 109 m:=(l+r) shr 1; 110 if x<=m then 111 begin 112 tree[q].r:=tree[last].r; 113 last:=tree[last].l; 114 tree[q].l:=add(last,l,m,x); 115 end 116 else begin 117 tree[q].l:=tree[last].l; 118 last:=tree[last].r; 119 tree[q].r:=add(last,m+1,r,x); 120 end; 121 update(q); 122 exit(q); 123 end; 124 end; 125 126 function getans(l,r,k:longint):longint; 127 var m,s1:longint; 128 begin 129 if l=r then 130 exit(sa[l]) 131 else begin 132 m:=(l+r) shr 1; 133 s1:=tree[tree[x].l].s+tree[tree[y].l].s-tree[tree[z].l].s-tree[tree[e].l].s; 134 if s1>=k then 135 begin 136 x:=tree[x].l; 137 y:=tree[y].l; 138 z:=tree[z].l; 139 e:=tree[e].l; 140 exit(getans(l,m,k)); 141 end 142 else begin 143 x:=tree[x].r; 144 y:=tree[y].r; 145 z:=tree[z].r; 146 e:=tree[e].r; 147 k:=k-s1; 148 exit(getans(m+1,r,k)); 149 end; 150 end; 151 end; 152 153 function lca(x,y:longint):longint; 154 var i,p,u,v:longint; 155 begin 156 if d[x]<d[y] then swap(x,y); 157 if x=y then exit(x); 158 p:=trunc(ln(d[x])/ln(2)); 159 if d[x]<>d[y] then 160 begin 161 for i:=p downto 0 do 162 if d[x]-1 shl i>=d[y] then x:=anc[x,i]; 163 end; 164 if x=y then exit(x); 165 u:=x; 166 v:=y; 167 for i:=p downto 0 do 168 if (anc[x,i]<>anc[y,i]) and (anc[x,i]<>0) then 169 begin 170 x:=anc[x,i]; 171 y:=anc[y,i]; 172 end; 173 174 exit(fa[x]); 175 end; 176 177 procedure maintain(x:longint); 178 var i,y:longint; 179 begin 180 for i:=1 to trunc(ln(n)/ln(2)) do 181 begin 182 y:=anc[x,i-1]; 183 anc[x,i]:=anc[y,i-1]; 184 end; 185 end; 186 187 procedure dfs(x:longint); 188 var i,y:longint; 189 begin 190 h[x]:=add(h[fa[x]],1,s,rank[x]); 191 maintain(x); 192 i:=p[x]; 193 while i<>0 do 194 begin 195 y:=w[i].po; 196 if fa[x]<>y then 197 begin 198 d[y]:=d[x]+1; 199 fa[y]:=x; 200 anc[y,0]:=x; 201 dfs(y); 202 end; 203 i:=w[i].next; 204 end; 205 end; 206 207 procedure connect(x,y:longint); 208 begin 209 fa[y]:=x; //这棵树内的父子关系会变化 210 anc[y,0]:=x; 211 d[y]:=d[x]+1; 212 dfs(y); 213 end; 214 215 begin 216 readln(testcase); 217 readln(n,e,m); 218 for i:=1 to n do 219 begin 220 read(a[i]); 221 c[i]:=i; 222 fs[i]:=i; 223 size[i]:=1; 224 end; 225 sort(1,n); 226 s:=1; 227 sa[1]:=a[1]; 228 rank[c[1]]:=1; 229 for i:=2 to n do 230 begin 231 if a[i]<>a[i-1] then 232 begin 233 inc(s); 234 sa[s]:=a[i]; 235 end; 236 rank[c[i]]:=s; 237 end; 238 239 for i:=1 to e do 240 begin 241 readln(x,y); 242 addedge(x,y); 243 addedge(y,x); 244 union; 245 end; 246 247 t:=0; 248 h[0]:=build(1,s); 249 for i:=1 to n do 250 if d[i]=0 then dfs(i); 251 252 ans:=0; 253 for i:=1 to m do 254 begin 255 read(ch); 256 if ch='Q' then 257 begin 258 readln(x,y,k); 259 x:=x xor ans; 260 y:=y xor ans; 261 k:=k xor ans; 262 z:=lca(x,y); 263 e:=h[fa[z]]; 264 z:=h[z]; 265 x:=h[x]; 266 y:=h[y]; 267 ans:=getans(1,s,k); 268 writeln(ans); 269 end 270 else begin 271 readln(x,y); 272 x:=x xor ans; 273 y:=y xor ans; 274 addedge(x,y); 275 addedge(y,x); 276 union; 277 connect(x,y); 278 end; 279 end; 280 end.