# [bzoj2588][Spoj 10628] Count on a tree

#include<iostream>
#include<cstdio>
#include<algorithm>
#define mp(x,y) make_pair(x,y)
#define MN 100000
#define ll long long
using namespace std;
{
//    int x;scanf("%lld",&x);return x;
ll x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}

ll last=0;
int n,m,mx[MN+5],size[MN+5],dfn[MN+5],dn=0,cnt=0,dep[MN+5],tot=1;
pair<int,int> q[MN+5];
struct node{int l,r,x;}T[MN*30];
struct edge{int to,next;}e[MN*2+5];

void ins(int f,int t)
{
}

void dfs1(int x,int f)
{
mx[x]=0;size[x]=1;fa[x]=f;
if(e[i].to!=f)
{
dep[e[i].to]=dep[x]+1;dfs1(e[i].to,x);
size[x]+=size[e[i].to];
if(size[e[i].to]>size[mx[x]]) mx[x]=e[i].to;
}
}

void dfs2(int x,int tp)
{
dfn[x]=++dn;p[dn]=x;top[x]=tp;
if(mx[x]) dfs2(mx[x],tp);
if(e[i].to!=fa[x]&&e[i].to!=mx[x])
dfs2(e[i].to,e[i].to);
}

void ins(int x,int nx,int k)
{
int l=1,r=tot,mid;
while(l<r)
{
mid=l+r>>1;
if(k<=mid)
{
T[nx].r=T[x].r;T[nx].l=++cnt;
x=T[x].l;nx=T[nx].l;r=mid;
}
else
{
T[nx].l=T[x].l;T[nx].r=++cnt;
x=T[x].r;nx=T[nx].r;l=mid+1;
}
T[nx].x=T[x].x+1;
}
}

void getrt(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
q[++tp]=mp(rt[dfn[x]],rt[dfn[top[x]]-1]);
x=fa[top[x]];
}
if(dfn[x]>dfn[y]) swap(x,y);
q[++tp]=mp(rt[dfn[y]],rt[dfn[x]-1]);
}

main()
{
sort(L+1,L+n+1);
for(int i=2;i<=n;i++) if(L[i]!=L[i-1]) L[++tot]=L[i];
for(int i=1;i<n;i++)
{
ins(u,v);
}
cnt=0;dfs1(1,0);dfs2(1,1);
for(int i=1;i<=n;i++) ins(rt[i-1],rt[i]=++cnt,(a[p[i]]=lower_bound(L+1,L+tot+1,a[p[i]])-L));
for(int i=1;i<=m;i++)
{
getrt(x,y);
int l=1,r=tot,mid;
while(l<r)
{
int sum=0;mid=l+r>>1;
for(int j=1;j<=tp;j++)
sum+=T[T[q[j].first].l].x-T[T[q[j].second].l].x;
if(sum<k)
{
k-=sum;l=mid+1;
for(int j=1;j<=tp;j++)
q[j]=mp(T[q[j].first].r,T[q[j].second].r);
}
else
{
r=mid;
for(int j=1;j<=tp;j++)
q[j]=mp(T[q[j].first].l,T[q[j].second].l);
}
}
printf("%lld",last=L[l]);if(i!=m) puts("");
}
return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MN 100000
#define MK 18
#define ll long long
using namespace std;
{
ll x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}

ll last=0;
struct node{int l,r,x;}T[MN*30];
struct edge{int to,next;}e[MN*2+5];

void ins(int f,int t)
{
}

void dfs1(int x,int f)
{
fa[x][0]=f;
if(e[i].to!=f) dep[e[i].to]=dep[x]+1,dfs1(e[i].to,x);
}

void ins(int x,int nx,int k)
{
int l=1,r=tot,mid;
while(l<r)
{
mid=l+r>>1;
if(k<=mid)
{
T[nx].r=T[x].r;T[nx].l=++cnt;
x=T[x].l;nx=T[nx].l;r=mid;
}
else
{
T[nx].l=T[x].l;T[nx].r=++cnt;
x=T[x].r;nx=T[nx].r;l=mid+1;
}
T[nx].x=T[x].x+1;
}
}

void init(int x)
{
ins(rt[fa[x][0]],rt[x]=++cnt,a[x]=lower_bound(L+1,L+tot+1,a[x])-L);
if(e[i].to!=fa[x][0]) init(e[i].to);
}

int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int k=dep[x]-dep[y],j=0;k;k>>=1,++j)
if(k&1) x=fa[x][j];
if(x==y) return x;
for(int i=MK;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}

int main()
{
sort(L+1,L+n+1);
for(int i=2;i<=n;i++) if(L[i]!=L[i-1]) L[++tot]=L[i];
for(int i=1;i<n;i++)
{
ins(u,v);
}
dfs1(1,0);cnt=0;init(1);
for(int i=1;i<=MK;i++)
for(int j=1;j<=n;j++)
fa[j][i]=fa[fa[j][i-1]][i-1];
for(int i=1;i<=m;i++)
{
int l=1,r=tot,mid;int z=rt[b=lca(x,y)];x=rt[x];y=rt[y];
while(l<r)
{
mid=l+r>>1;int sum=T[T[x].l].x+T[T[y].l].x-2*T[T[z].l].x+(a[b]>=l&&a[b]<=mid);
if(sum<k) k-=sum,x=T[x].r,y=T[y].r,z=T[z].r,l=mid+1;
else x=T[x].l,y=T[y].l,z=T[z].l,r=mid;
}
printf("%lld",last=L[l]);if(i!=m) puts("");
}
return 0;
}

posted @ 2017-04-11 22:11  FallDream  阅读(186)  评论(0编辑  收藏  举报