一开始一看树上的操作,就无脑写了树链剖分+主席树
然后果断T了,因为树链剖分+主席树必然带来两个log的复杂度
而且树链剖分复杂度还比较大……
后来发现其实没必要,在这道题,我们可以直接利用主席树维护
只不过,每个点维护的是它到它的祖先上数值出现的个数
则u,v之间各个数值出现的数值=tree[u]+tree[v]-tree[lca(u,v)]-tree[fa[lca(u,v)]];
这是一个满足区间减法的问题所以可以这么做
总结一下,在静态树上(相对于动态树而言,没有改变树的形态)
-
如果问题满足区间减法性质,如求k大,那就直接做,或者用dfs序(下篇再写)
-
如果不满足,那就要套树链剖分了
1 const maxn=100010; 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*20] of point; 10 w:array[0..2*maxn] of node; 11 h,p,c,b,a,q1,q2,rank,sa,fa,d:array[0..maxn] of longint; 12 anc:array[0..maxn,0..20] of longint; 13 j,t,z,e,i,n,m,k,x,y,len,ans,s:longint; 14 15 procedure swap(var a,b:longint); 16 var c:longint; 17 begin 18 c:=a; 19 a:=b; 20 b:=c; 21 end; 22 23 procedure update(i:longint); 24 begin 25 tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s; 26 end; 27 28 procedure add(x,y:longint); 29 begin 30 inc(len); 31 w[len].po:=y; 32 w[len].next:=p[x]; 33 p[x]:=len; 34 end; 35 36 procedure sort(l,r: longint); 37 var i,j,x:longint; 38 begin 39 i:=l; 40 j:=r; 41 x:=a[(l+r) div 2]; 42 repeat 43 while (a[i]<x) do inc(i); 44 while (x<a[j]) do dec(j); 45 if not(i>j) then 46 begin 47 swap(a[i],a[j]); 48 swap(c[i],c[j]); 49 inc(i); 50 j:=j-1; 51 end; 52 until i>j; 53 if l<j then sort(l,j); 54 if i<r then sort(i,r); 55 end; 56 57 function build(l,r:longint):longint; 58 var q,m:longint; 59 begin 60 inc(t); 61 if l=r then exit(t) 62 else begin 63 q:=t; 64 m:=(l+r) shr 1; 65 tree[q].l:=build(l,m); 66 tree[q].r:=build(m+1,r); 67 exit(q); 68 end; 69 end; 70 71 function add(last,l,r,x:longint):longint; 72 var q,m:longint; 73 begin 74 inc(t); 75 if l=r then 76 begin 77 tree[t].s:=tree[last].s+1; 78 exit(t); 79 end 80 else begin 81 q:=t; 82 m:=(l+r) shr 1; 83 if x<=m then 84 begin 85 tree[q].r:=tree[last].r; 86 last:=tree[last].l; 87 tree[q].l:=add(last,l,m,x); 88 end 89 else begin 90 tree[q].l:=tree[last].l; 91 last:=tree[last].r; 92 tree[q].r:=add(last,m+1,r,x); 93 end; 94 update(q); 95 exit(q); 96 end; 97 end; 98 99 function getans(l,r,k:longint):longint; 100 var i,m,s1:longint; 101 begin 102 if l=r then 103 exit(sa[l]) 104 else begin 105 m:=(l+r) shr 1; 106 s1:=tree[tree[x].l].s+tree[tree[y].l].s-tree[tree[z].l].s-tree[tree[e].l].s; 107 if s1>=k then 108 begin 109 x:=tree[x].l; 110 y:=tree[y].l; 111 z:=tree[z].l; 112 e:=tree[e].l; 113 exit(getans(l,m,k)); 114 end 115 else begin 116 x:=tree[x].r; 117 y:=tree[y].r; 118 z:=tree[z].r; 119 e:=tree[e].r; 120 k:=k-s1; 121 exit(getans(m+1,r,k)); 122 end; 123 end; 124 end; 125 126 function lca(x,y:longint):longint; 127 var i,p:longint; 128 begin 129 if d[x]<d[y] then swap(x,y); 130 if x=y then exit(x); 131 p:=trunc(ln(d[x])/ln(2)); 132 for i:=p downto 0 do 133 if d[x]-1 shl i>=d[y] then x:=anc[x,i]; 134 if x=y then exit(x); 135 for i:=p downto 0 do 136 if (anc[x,i]<>anc[y,i]) and (anc[x,i]<>0) then 137 begin 138 x:=anc[x,i]; 139 y:=anc[y,i]; 140 end; 141 exit(fa[x]); 142 end; 143 144 procedure dfs(x:longint); 145 var i,y:longint; 146 begin 147 h[x]:=add(h[fa[x]],1,s,rank[x]); 148 i:=p[x]; 149 while i<>0 do 150 begin 151 y:=w[i].po; 152 if fa[x]<>y then 153 begin 154 d[y]:=d[x]+1; 155 fa[y]:=x; 156 dfs(y); 157 end; 158 i:=w[i].next; 159 end; 160 end; 161 162 begin 163 readln(n,m); 164 for i:=1 to n do 165 begin 166 read(a[i]); 167 c[i]:=i; 168 end; 169 sort(1,n); 170 s:=1; 171 sa[1]:=a[1]; 172 rank[c[1]]:=1; 173 for i:=2 to n do 174 begin 175 if a[i]<>a[i-1] then 176 begin 177 inc(s); 178 sa[s]:=a[i]; 179 end; 180 rank[c[i]]:=s; 181 end; 182 for i:=1 to n-1 do 183 begin 184 readln(x,y); 185 add(x,y); 186 add(y,x); 187 end; 188 h[0]:=build(1,s); 189 dfs(1); 190 191 for i:=1 to n do 192 anc[i,0]:=fa[i]; 193 k:=trunc(ln(n)/ln(2)); 194 for j:=1 to k do 195 for i:=1 to n do 196 begin 197 x:=anc[i,j-1]; 198 if x<>0 then anc[i,j]:=anc[x,j-1]; 199 end; 200 201 ans:=0; 202 for i:=1 to m do 203 begin 204 readln(x,y,k); 205 x:=x xor ans; 206 z:=lca(x,y); 207 e:=h[fa[z]]; 208 z:=h[z]; 209 x:=h[x]; 210 y:=h[y]; 211 ans:=getans(1,s,k); 212 write(ans); 213 if i<>m then writeln; 214 end; 215 end.