您的位置:首页 > 其它

BZOJ 4539: [Hnoi2016]树

2016-04-19 11:51 381 查看
md强行凑数据结构题,树剖+主席树,各种函数搞一大堆查询,然后其实就是求两点的lca。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100000+5;
#define rep(i,l,r) for(int i=l;i<=r;i++)
typedef long long ll;
ll read(){
char ch=getchar();ll x=0,f=1;
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;
}
struct Edge{int to,next;}e[N<<1],g[N<<1];
int head
,cnt,last
,tot;
void ins1(int u,int v){e[++cnt]=(Edge){v,head[u]};head[u]=cnt;}
void insert1(int u,int v){ins1(u,v);ins1(v,u);}
void ins2(int u,int v){g[++tot]=(Edge){v,last[u]};last[u]=tot;}
void insert2(int u,int v){ins2(u,v);ins2(v,u);}
int fa1
,dep1
,top1
,son1
,siz1
,st
,ed
,dfn
,sz;
void dfs1(int u){
dfn[st[u]=++sz]=u;siz1[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;if(v==fa1[u])continue;
fa1[v]=u;dep1[v]=dep1[u]+1;dfs1(v);
siz1[u]+=siz1[v];if(siz1[v]>siz1[son1[u]])son1[u]=v;
}
ed[u]=sz;
}
void dfs1(int u,int tp){
top1[u]=tp;
if(son1[u])dfs1(son1[u],tp);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v!=fa1[u]&&v!=son1[u])dfs1(v,v);
}
}
struct Node{
int lc,rc,w;
}tr[N*20];
int node,root
;
void build(int &o,int l,int r){
o=++node;
if(l==r)return;
int mid=l+r>>1;
build(tr[o].lc,l,mid);build(tr[o].rc,mid+1,r);
}
void insert(int &o,int l,int r,int p){
tr[++node]=tr[o];o=node;
tr[o].w++;
if(l==r)return;
int mid=l+r>>1;
if(p<=mid)insert(tr[o].lc,l,mid,p);
else insert(tr[o].rc,mid+1,r,p);
}
int query(int x,int y,int l,int r,int k){
if(l==r)return l;
int mid=l+r>>1;
int sum=tr[tr[y].lc].w-tr[tr[x].lc].w;
if(k<=sum)
return query(tr[x].lc,tr[y].lc,l,mid,k);
else return query(tr[x].rc,tr[y].rc,mid+1,r,k-sum);
}
int rank(int x,int y,int l,int r,int k){
if(l==r)return tr[y].w-tr[x].w;
int mid=l+r>>1;
if(k<=mid)return rank(tr[x].lc,tr[y].lc,l,mid,k);
else return rank(tr[x].rc,tr[y].rc,mid+1,r,k)+tr[tr[y].lc].w-tr[tr[x].lc].w;
}
int query(int u,int k){
return query(root[st[u]-1],root[ed[u]],1,sz,k);
}
int rank(int u,int k){
return rank(root[st[u]-1],root[ed[u]],1,sz,k);
}
int fa2
,dep2
,siz2
,son2
,top2
,cost
;
ll depth
;
void dfs2(int u){
siz2[u]=1;
for(int i=last[u];i;i=g[i].next){
int v=g[i].to;if(v==fa2[u])continue;
dep2[v]=dep2[u]+1;fa2[v]=u;depth[v]=depth[u]+cost[v];dfs2(v);
siz2[u]+=siz2[v];if(siz2[v]>siz2[son2[u]])son2[u]=v;
}
}
void dfs2(int u,int tp){
top2[u]=tp;
if(son2[u])dfs2(son2[u],tp);
for(int i=last[u];i;i=g[i].next){
int v=g[i].to;
if(v!=son2[u]&&v!=fa2[u])dfs2(v,v);
}
}
ll size
;
int n,m,now;
int belong(ll id){
int l=1,r=now;
while(l<=r){
int mid=l+r>>1;
if(size[mid]<id)l=mid+1;
else r=mid-1;
}
return l-1;
}
int lca1(int u,int v){
while(top1[u]!=top1[v]){
if(dep1[top1[u]]<dep1[top1[v]])swap(u,v);
u=fa1[top1[u]];
}
return dep1[u]<dep1[v]?u:v;
}
ll li
;
int rt
;
ll lca2(ll u,ll v){
int x=belong(u),y=belong(v);
while(top2[x]!=top2[y]){
if(dep2[top2[x]]<dep2[top2[y]])swap(x,y),swap(u,v);
x=top2[x];u=li[x];x=fa2[x];
}
if(x!=y){
if(dep2[x]>dep2[y])swap(x,y),swap(u,v);
y=x;v=li[son2[y]];
}
return size[x]+rank(rt[x],lca1(query(rt[x],u-size[x]),query(rt[y],v-size[y])));
}
ll dep(ll u){
int x=belong(u);
return depth[x]+dep1[query(rt[x],u-size[x])]-dep1[rt[x]];
}
ll dist(ll u,ll v){
return dep(u)+dep(v)-2*dep(lca2(u,v));
}
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int q;n=read();m=read();q=read();
rep(i,2,n){int u,v;u=read();v=read();insert1(u,v);}
dfs1(1);dfs1(1,1);
build(root[0],1,sz);
rep(i,1,sz){
root[i]=root[i-1];
insert(root[i],1,sz,dfn[i]);
}
rt[1]=1;m++;now=1;
rep(i,2,m){
rt[i]=read();li[i]=read();size[i]=size[i-1]+siz1[rt[i-1]];
int x=belong(li[i]);
insert2(i,x);
cost[i]=dep1[query(rt[x],li[i]-size[x])]-dep1[rt[x]]+1;
now++;
}
dfs2(1);dfs2(1,1);
while(q--){
ll u,v;u=read();v=read();
printf("%lld\n",dist(u,v));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: