每个点的主席树的root是从其父转移来的。询问的时候用U+V-LCA-FA(LCA)即可。
#include<cstdio> #include<algorithm> using namespace std; #define N 100001 int v[N<<1],first[N],next[N<<1],en,Ans; void AddEdge(int U,int V) { v[++en]=V; next[en]=first[U]; first[U]=en; } struct Point{int v,p;}t[N]; bool operator < (Point a,Point b){return a.v<b.v;} int n,m,ma[N],a[N],zy; struct Node{int v,lc,rc;}T[N*24]; int root[N],e=1; void BuildTree(int cur,int l,int r) { if(l==r) return; int m=(l+r>>1); T[cur].lc=++e; BuildTree(T[cur].lc,l,m); T[cur].rc=++e; BuildTree(T[cur].rc,m+1,r); } void Insert(int pre,int cur,int p,int l,int r) { if(l==r) { T[cur].v=T[pre].v+1; return; } int m=(l+r>>1); if(p<=m) { T[cur].lc=++e; T[cur].rc=T[pre].rc; Insert(T[pre].lc,T[cur].lc,p,l,m); } else { T[cur].rc=++e; T[cur].lc=T[pre].lc; Insert(T[pre].rc,T[cur].rc,p,m+1,r); } T[cur].v=T[T[cur].lc].v+T[T[cur].rc].v; } int top[N],siz[N],son[N],fa[N],dep[N]; void df1(int U) { siz[U]=1; for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) { fa[v[i]]=U; dep[v[i]]=dep[U]+1; df1(v[i]); siz[U]+=siz[v[i]]; if(siz[v[i]]>siz[son[U]]) son[U]=v[i]; } } void df2(int U) { if(son[U]) { top[son[U]]=top[U]; df2(son[U]); } for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]&&v[i]!=son[U]) { top[v[i]]=v[i]; df2(v[i]); } } int lca(int U,int V) { while(top[U]!=top[V]) { if(dep[top[U]]<dep[top[V]]) swap(U,V); U=fa[top[U]]; } if(dep[U]>dep[V]) swap(U,V); return U; } void dfs(int U) { root[U]=++e; Insert(root[fa[U]],root[U],a[U],1,zy); for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) dfs(v[i]); } int Kth(int ql,int qr,int LCA,int FLCA,int K,int l,int r) { if(l==r) return l; int m=(l+r>>1); if(T[T[ql].lc].v+T[T[qr].lc].v-T[T[LCA].lc].v-T[T[FLCA].lc].v>=K) return Kth(T[ql].lc,T[qr].lc,T[LCA].lc,T[FLCA].lc,K,l,m); else return Kth(T[ql].rc,T[qr].rc,T[LCA].rc,T[FLCA].rc,K-(T[T[ql].lc].v+T[T[qr].lc].v-T[T[LCA].lc].v-T[T[FLCA].lc].v),m+1,r); } int main() { int X,Y,W; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&t[i].v); t[i].p=i; } sort(t+1,t+n+1); a[t[1].p]=++zy; ma[zy]=t[1].v; for(int i=2;i<=n;++i) { if(t[i].v!=t[i-1].v) ++zy; a[t[i].p]=zy; ma[zy]=t[i].v; } for(int i=1;i<n;++i) { scanf("%d%d",&X,&Y); AddEdge(X,Y); AddEdge(Y,X); } root[0]=1; BuildTree(root[0],1,zy); df1(1); top[1]=1; df2(1); dfs(1); for(;m;--m) { scanf("%d%d%d",&X,&Y,&W); X^=Ans; int t=lca(X,Y); printf("%d",Ans=ma[Kth(root[X],root[Y],root[t],root[fa[t]],W,1,zy)]); if(m!=1) puts(""); } return 0; }
时间: 2024-10-27 17:59:42