http://www.lydsy.com/JudgeOnline/problem.php?id=2588
在树上建主席树
每个节点按它的father建一颗新树
对于路径(u,v)等价于(1,u)+(1,v)-(1,lca(u,v))-(1,fa[lca(u,v)])
root[u],root[v],root[lca(u,v)],root[fa[lca(u,v)]]
然后在这4棵主席树上差分,取出k小值
#include<cstdio> #include<algorithm> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using namespace std; const int N=100011,NlogN=2000011; struct Tree{ int ls,rs,sum; #define ls(now) (tr[now].ls) #define rs(now) (tr[now].rs) #define sum(now) (tr[now].sum) }tr[NlogN]; int rt[N]; int n,m,ans,a[N],b[N]; int x,y,p,k,cnt; inline void disc_init(){ sort(b+1,b+b[0]+1); b[0]=unique(b+1,b+b[0]+1)-b-1; FOR(i,1,n)a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b; } struct edge{ int to;edge *nxt; #define VIS(now) for(edge *it=las[now];it;it=it->nxt) #define to(it) (it->to) }e[N<<1],*las[N],*tot=e; int top[N],fa[N],dep[N],sz[N]; inline void add(int x,int y){ *++tot=(edge){y,las[x]},las[x]=tot; } inline void dfs1(int now){ int to;sz[now]=1; VIS(now) if(!dep[to(it)]){ dep[to(it)]=dep[now]+1;fa[to(it)]=now; dfs1(to(it));sz[now]+=sz[to(it)]; } } inline void build(int cpy,int &now,int l,int r,int pos){ tr[now=++cnt]=tr[cpy];++sum(now); if(l==r)return;int mid=(l+r)>>1; pos<=mid?build(ls(cpy),ls(now),l,mid,pos):build(rs(cpy),rs(now),mid+1,r,pos); } inline int query(int a,int b,int c,int d,int l,int r,int k){ if(l==r)return l; int data=sum(ls(a))+sum(ls(b))-sum(ls(c))-sum(ls(d)); int mid=(l+r)>>1; return k<=data?query(ls(a),ls(b),ls(c),ls(d),l,mid,k):query(rs(a),rs(b),rs(c),rs(d),mid+1,r,k-data); } inline void dfs2(int now,int chain){ top[now]=chain;build(rt[fa[now]],rt[now],1,b[0],a[now]); register int i=0; VIS(now)if(fa[now]!=(to(it))&&sz[to(it)]>sz[i])i=to(it); if(!i)return;dfs2(i,chain); VIS(now)if(fa[now]!=(to(it))&&i!=to(it))dfs2(to(it),to(it)); } inline int lca(int x,int y){ for(;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 main(){ scanf("%d%d",&n,&m); FOR(i,1,n)scanf("%d",a+i),b[++b[0]]=a[i]; disc_init(); FOR(i,2,n){ scanf("%d%d",&x,&y); add(x,y);add(y,x); } dep[1]=1;dfs1(1);dfs2(1,1); while(m--){ scanf("%d%d%d",&x,&y,&k); x^=ans;p=lca(x,y); ans=b[query(rt[x],rt[y],rt[p],rt[fa[p]],1,b[0],k)]; printf("%d",ans); if(m)putchar(' '); } return 0; }