# 【BZOJ2588】【Spoj10628】—Count on a tree（主席树）

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<21|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
return (ob==ib)?EOF:*ib++;
}
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
const int N=100005;
namespace Ptree{
#define mid ((l+r)>>1)
int rt[N],lc[N*22],rc[N*22],sum[N*22],tot;
void insert(int &u,int r1,int l,int r,int k){
u=++tot,lc[u]=lc[r1],rc[u]=rc[r1],sum[u]=sum[r1]+1;
if(l==r)return;
if(k<=mid)insert(lc[u],lc[r1],l,mid,k);
else insert(rc[u],rc[r1],mid+1,r,k);
}
int query(int r1,int r2,int r3,int r4,int l,int r,int k){
if(l==r)return l;
int num=sum[lc[r4]]+sum[lc[r3]]-sum[lc[r1]]-sum[lc[r2]];
if(k<=num)return query(lc[r1],lc[r2],lc[r3],lc[r4],l,mid,k);
else return query(rc[r1],rc[r2],rc[r3],rc[r4],mid+1,r,k-num);
}
}
using namespace Ptree;
void dfs1(int u){
siz[u]=1;insert(rt[u],rt[fa[u]],1,cnt,val[u]);
int v=to[e];
if(v==fa[u])continue;
fa[v]=u,dep[v]=dep[u]+1;
dfs1(v),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;
if(son[u])dfs2(son[u],tp);
int v=to[e];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
inline 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]];
}
return dep[u]>dep[v]?v:u;
}
}
int main(){
for(int i=1;i<n;i++){
}
cnt=0;
sort(a+1,a+n+1);
cnt=unique(a+1,a+n+1)-a-1;
for(int i=1;i<=n;i++)val[i]=lower_bound(a+1,a+cnt+1,val[i])-a;
dfs1(1),dfs2(1,1);
while(m--){
int lca=Lca(u,v);
cout<<(last=a[query(rt[fa[lca]],rt[lca],rt[u],rt[v],1,cnt,k)])<<'\n';
}
}

posted @ 2019-04-24 17:32  Stargazer_cykoi  阅读(61)  评论(0编辑  收藏  举报