对于每个点建立一颗主席树;
然后按照树上差分的思想统计主席树的前缀和;
lca+主席树+前向星存表就可以了;
#include <bits/stdc++.h> #define inc(i,a,b) for(register int i=a;i<=b;i++) #define dec(i,a,b) for(register int i=a;i>=b;i--) using namespace std; int head[2000010],cnt; class littlestar{ public: int to; int nxt; }star[2000010]; void add(int u,int v){ star[++cnt].to=v; star[cnt].nxt=head[u]; head[u]=cnt; } int n,m; template<class nT> inline void read(nT& x) { char c; while(c=getchar(),!isdigit(c)); x=c^48; while(c=getchar(),isdigit(c)) x=x*10+c-48; } int a[2000010],val[2000010]; int dep[2000010],f[1000010][30]; void pre(int u,int fa) { //printf("%d %d ",u,fa); dep[u]=dep[fa]+1; inc(i,0,20){ f[u][i+1]=f[f[u][i]][i]; } for(register int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(v==fa) continue; f[v][0]=u; pre(v,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); dec(i,19,0){ if(dep[f[x][i]]>=dep[y]) x=f[x][i]; if(x==y) return x; } dec(i,19,0){ if(f[x][i]!=f[y][i]){ x=f[x][i]; y=f[y][i]; } } return f[x][0]; } int rt[20000010]; int num=0; class node2{ public: int l; int r; int w; }tree[20000010]; void insert(int preroot,int &root,int l,int r,int goal){ tree[root=++num]=tree[preroot]; tree[root].w++; if(l==r) return; int mid=(l+r)>>1; if(goal<=mid){ insert(tree[preroot].l,tree[root].l,l,mid,goal); } else{ insert(tree[preroot].r,tree[root].r,mid+1,r,goal); } tree[root].w=(tree[tree[root].l].w+tree[tree[root].r].w); } int query(int l,int r,int x,int y,int lc,int falc,int k){ if(l==r) return l; int tmp=tree[tree[x].l].w+tree[tree[y].l].w-tree[tree[lc].l].w-tree[tree[falc].l].w; int mid=(l+r)>>1; if(k<=tmp){ return query(l,mid,tree[x].l,tree[y].l,tree[lc].l,tree[falc].l,k); } else{ return query(mid+1,r,tree[x].r,tree[y].r,tree[lc].r,tree[falc].r,k-tmp); } } void dfs(int u) { insert(rt[f[u][0]],rt[u],1,n,val[u]); for(register int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(v==f[u][0]) continue; dfs(v); } } int ago[2000010]; signed main() { //freopen("ha.in","r",stdin); read(n); read(m); inc(i,1,n) read(a[i]),val[i]=a[i]; inc(i,1,n-1){ int u,v; read(u); read(v); add(u,v); add(v,u); } sort(a+1,a+1+n); int lisan=unique(a+1,a+1+n)-a-1; inc(i,1,n){ int tmp=val[i]; val[i]=lower_bound(a+1,a+1+lisan,val[i])-a; ago[val[i]]=tmp; } pre(1,0); dfs(1); int onlineans=0; inc(i,1,m){ int u,v,k; read(u);read(v);read(k); u^=onlineans; int LCA=lca(u,v); int last=query(1,n,rt[u],rt[v],rt[LCA],rt[f[LCA][0]],k); onlineans=ago[last]; printf("%d ",onlineans); } }