在树上建主席树,每个点以它的父亲节点作为历史版本。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 200005
using namespace std;
struct E{
int to,nxt;
}b[maxn<<1];
int fst[maxn],tot=1;
void build(int f,int t)
{
b[++tot]=(E){t,fst[f]};fst[f]=tot;
b[++tot]=(E){f,fst[t]};fst[t]=tot;
}
int deep[maxn];
int fa[maxn][20];
int w[maxn],L[maxn],len;
int lca(int u,int v)
{
if(deep[u]>deep[v])
swap(u,v);
int t=deep[v]-deep[u];
for(int i=0;i<=17;i++)
if((t>>i)&1) v=fa[v][i];
if(u==v) return u;
for(int i=17;i>=0;i--)
if(fa[v][i]!=fa[u][i])
{
v=fa[v][i];
u=fa[u][i];
}
return fa[u][0];
}
int Rt[maxn];
struct zxs{
int l,r,cnt;
}tree[4000005];
int T=0;
void insert(int l,int r,int x,int &y,int v)
{
y=++T;
tree[y]=tree[x];
tree[y].cnt++;
if(l==r) return;
int mid=(l+r)>>1;
if(v<=mid) insert(l,mid,tree[x].l,tree[y].l,v);
else insert(mid+1,r,tree[x].r,tree[y].r,v);
}
int ask(int x,int y,int f,int k)
{
x=Rt[x];y=Rt[y];
int z=fa[f][0];f=Rt[f];z=Rt[z];
int l=1,r=len;
while(l<r)
{
int p=tree[tree[y].l].cnt+tree[tree[x].l].cnt;
p-=tree[tree[f].l].cnt+tree[tree[z].l].cnt;
int mid=(l+r)>>1;
if(p>=k)
{
r=mid;
x=tree[x].l;
y=tree[y].l;
f=tree[f].l;
z=tree[z].l;
}
else
{
l=mid+1;
x=tree[x].r;
y=tree[y].r;
f=tree[f].r;
z=tree[z].r;
k-=p;
}
}
return L[l];
}
int n,m;
void dfs(int x)
{
for(int i=1;i<=17;i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
int j=lower_bound(L+1,L+len+1,w[x])-L;
insert(1,len,Rt[fa[x][0]],Rt[x],j);
for(int i=fst[x];i;i=b[i].nxt)
{
int v=b[i].to;
if(!deep[v])
{
deep[v]=deep[x]+1;
fa[v][0]=x;
dfs(v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
L[i]=w[i];
}
sort(L+1,L+n+1);
len=unique(L+1,L+n+1)-L-1;
int x,y,k;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
build(x,y);
}
deep[1]=1;
dfs(1);
int lst=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&k);
x^=lst;
lst=ask(x,y,lca(x,y),k);
printf("%d",lst);
if(i!=m) puts("");
}
return 0;
}