题解:主席树,上一层为父亲节点对应的主席树
查询就用 u+v-lca-fa[lca]即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200009;
int n,m;
int lastans;
int v[maxn];
int cntedge;
int head[maxn];
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
}
int b[maxn],nn;
int root[maxn];
int PTsiz;
struct PresidentTree{
int l,r,d,ls,rs;
}tree[maxn*20];
void BuildTree(int &now,int l,int r){
now=++PTsiz;
tree[now].l=l;tree[now].r=r;tree[now].d=0;
if(l==r)return;
int mid=(l+r)>>1;
BuildTree(tree[now].ls,l,mid);
BuildTree(tree[now].rs,mid+1,r);
}
void Updatapoint(int &now,int pre,int p){
now=++PTsiz;
tree[now]=tree[pre];
tree[now].d++;
if(tree[now].l==tree[now].r)return;
int mid=(tree[now].l+tree[now].r)>>1;
if(p<=mid)Updatapoint(tree[now].ls,tree[pre].ls,p);
else Updatapoint(tree[now].rs,tree[pre].rs,p);
}
int Querykth(int x,int y,int z,int w,int k){
if(tree[x].l==tree[x].r)return b[tree[x].l];
int d=tree[tree[x].ls].d+tree[tree[y].ls].d-tree[tree[z].ls].d-tree[tree[w].ls].d;
if(k<=d)return Querykth(tree[x].ls,tree[y].ls,tree[z].ls,tree[w].ls,k);
else return Querykth(tree[x].rs,tree[y].rs,tree[z].rs,tree[w].rs,k-d);
}
int f[maxn][20];
int depth[maxn];
void Dfs(int now,int fa){
f[now][0]=fa;
depth[now]=depth[fa]+1;
int p=lower_bound(b+1,b+1+nn,v[now])-b;
Updatapoint(root[now],root[fa],p);
for(int i=head[now];i;i=nex[i]){
if(to[i]==fa)continue;
Dfs(to[i],now);
}
}
void LCAinit(){
for(int j=1;j<=19;++j){
for(int i=1;i<=n;++i){
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int Querylca(int u,int v){
if(depth[u]<depth[v])swap(u,v);
for(int j=19;j>=0;--j){
if(depth[f[u][j]]>=depth[v])u=f[u][j];
}
if(u==v)return u;
for(int j=19;j>=0;--j){
if(f[u][j]!=f[v][j]){
u=f[u][j];v=f[v][j];
}
}
return f[u][0];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&v[i]);b[i]=v[i];
}
sort(b+1,b+1+n);
nn=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n-1;++i){
int x,y;scanf("%d%d",&x,&y);
Addedge(x,y);Addedge(y,x);
}
BuildTree(root[0],1,n);
Dfs(1,0);
LCAinit();
while(m--){
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
u^=lastans;
int lca=Querylca(u,v);
printf("%d",lastans=Querykth(root[u],root[v],root[lca],root[f[lca][0]],k));
if(m!=0)printf("\n");
}
return 0;
}