【主席树】bzoj2588 Spoj 10628. Count on a tree
每个点的主席树的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;
}
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/

浙公网安备 33010602011771号
