題意
偉大的樹上權值第k小。
解析
在樹上建立主席樹,每個點的前驅不再是它的前一個點,而是它的父親結點。我們可以這樣來想,序列上的主席樹類似於前綴和,用的時候直接序列上差分。而樹上也就可以把每個點保存爲到根的主席樹,查詢的時候也類比樹上的差分就可以了。
記得是Query(rt[x],rt[y]….)。
#include <cstdio>
#include <algorithm>
#define Rep( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i<=(i##_END);i++)
#define For( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i++)
#define Lop( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i>=(i##_END);i--)
#define Dnt( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i--)
using std :: max;
using std :: min;
const int maxx = 100000 + 25;
typedef int Array[maxx];
int n,m,x,y,z,tot,cnt,num,lastans,Totnum;
int head[maxx],to[maxx<<1],nxt[maxx<<1];
int rt[maxx],lc[maxx*20],rc[maxx*20],T[maxx*20];
Array a,b,v,top,dpt,son,ftr,rnk,size;
namespace Pre_Tree{
void insert(int &i,int pre,int l,int r,int pos){
T[i=++cnt] = T[pre] + 1;
if(l == r) return;
lc[i] = lc[pre];rc[i] = rc[pre];
int mid = (l+r) >> 1;
if(pos <= mid) insert(lc[i],lc[pre],l,mid,pos);
if(pos > mid) insert(rc[i],rc[pre],mid+1,r,pos);
}
int Query(int x,int y,int L,int Fl,int l,int r,int k){
if(l == r) return l;
int mid = (l+r) >> 1;
int tmp = T[lc[x]] + T[lc[y]] - T[lc[L]] - T[lc[Fl]];
if(tmp < k) return Query(rc[x],rc[y],rc[L],rc[Fl],mid+1,r,k - tmp);
if(tmp >= k) return Query(lc[x],lc[y],lc[L],lc[Fl],l,mid,k) ;
}
}
using namespace Pre_Tree;
namespace Cute{
void Ins(int x,int y){
to[++num] = y;nxt[num] = head[x];head[x] = num;
}
void Dfs(int x){
size[x] = 1;
insert(rt[x],rt[ftr[x]],1,Totnum,v[x]);
for(int i=head[x];i;i=nxt[i]){
if(to[i] == ftr[x]) continue;
dpt[to[i]] = dpt[x] + 1;
ftr[to[i]] = x;
Dfs(to[i]);size[x] += size[to[i]];
if(size[to[i]] > size[son[x]]) son[x] = to[i];
}
}
void __Dfs(int x,int brn){
rnk[x] = ++tot;top[x] = brn;
if(son[x]) __Dfs(son[x],brn);
for(int i=head[x];i;i=nxt[i])
if(to[i] != son[x] && to[i] != ftr[x])
__Dfs(to[i],to[i]);
}
int Lca(int x,int y){
while(top[x] != top[y]){
if(dpt[top[x]] > dpt[top[y]]) std :: swap(x,y);
y = ftr[top[y]];
}
return dpt[x] < dpt[y]? x : y;
}
}
using namespace Cute;
int main(){
scanf("%d%d",&n,&m);
Rep( i , 1 , n ) scanf("%d",&a[i]),b[i] = a[i];
std :: sort(b+1,b+n+1);
Totnum = std :: unique(b+1,b+n+1) - b - 1;
Rep( i , 1 , n ) v[i] = std :: lower_bound(b+1,b+Totnum+1,a[i]) - b;
For( i , 1 , n ) scanf("%d%d",&x,&y),Ins(x,y),Ins(y,x);
Dfs(1);__Dfs(1,1);
while( m-- ){
scanf("%d%d%d",&x,&y,&z);
x ^= lastans;
lastans = b[Query(rt[x],rt[y],rt[Lca(x,y)],rt[ftr[Lca(x,y)]],1,Totnum,z)];
printf("%d",lastans);
if(m != 0) putchar(10);
}
return 0;
}