其实和luogu上主席树的板子差不多,就是把它放到了树上,把板子改成求sum[u]+sum[v]-sum[lca]-sum[lcafa]的就行了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100005;
struct Edge{int to,nxt;}e[N<<1];
int tim,dfn1[N],dfn2[N],top[N],son[N],siz[N],fa[N],dep[N],head[N],ecnt,rt[N<<5],a[N],b[N],u,n,m;
void add(int bg,int ed) {e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
void dfs(int x) {
siz[x]=1;
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(v==fa[x]) continue;
fa[v]=x,dep[v]=dep[x]+1;
dfs(v);siz[x]+=siz[v];
if(siz[v]>siz[son[x]]) son[x]=v;
}
}
void dfs(int x,int qtop) {
top[x]=qtop;dfn1[x]=++tim;
if(!son[x]) return;
dfs(son[x],qtop);
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(v==son[x]||v==fa[x]) continue;
dfs(v,v);
}
dfn2[x]=tim;
}
int ls[N<<5],rs[N<<5],sum[N<<5],tot;
void build(int &k,int l,int r) {
k=++tot;
if(l<r) {
int mid=l+r>>1;
build(ls[k],l,mid);
build(rs[k],mid+1,r);
}
}
void update(int &k,int l,int r,int pre,int c) {
ls[k=++tot]=ls[pre],rs[k]=rs[pre],sum[k]=sum[pre]+1;
if(l<r) {
int mid=l+r>>1;
if(c<=mid) update(ls[k],l,mid,ls[pre],c);
else update(rs[k],mid+1,r,rs[pre],c);
}
}
int query(int u,int v,int lca,int lcafa,int l,int r,int kth) {
if(l==r) return l;
int nowsiz=sum[ls[u]]+sum[ls[v]]-sum[ls[lca]]-sum[ls[lcafa]],mid=l+r>>1;
if(nowsiz<kth) return query(rs[u],rs[v],rs[lca],rs[lcafa],mid+1,r,kth-nowsiz);
return query(ls[u],ls[v],ls[lca],ls[lcafa],l,mid,kth);
}
void chairman(int x) {
update(rt[x],1,u,rt[fa[x]],a[x]);
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(v!=fa[x]) chairman(v);
}
}
int LCA(int x,int y) {
while(top[x]!=top[y])
(dep[top[x]]>=dep[top[y]])?x=fa[top[x]]:y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
int lastans;
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
for(int i=1,x,y;i<n;i++) {
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
sort(b+1,b+1+n);
u=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+u,a[i])-b;
build(rt[0],1,u);
dfs(1);dfs(1,1);
chairman(1);
int lca,xx,v,k;
while(m--) {
scanf("%d%d%d",&xx,&v,&k);
xx^=lastans;
lca=LCA(xx,v);
printf("%d
",lastans=b[query(rt[xx],rt[v],rt[lca],rt[fa[lca]],1,u,k)]);
}
}