首页 > 代码库 > bzoj4285: 使者
bzoj4285: 使者
搞出dfs序,转化为查询矩形点数,树套树搞定。
#include<cstdio>#include<cstdlib>#define N 100005#define IF else ifstruct edge{ edge* s; int v;}z[N*2],*next=z,*h[N];int n,m,q;void add(int u,int v){ h[u]=&(*next++ =(edge){h[u],v}); h[v]=&(*next++ =(edge){h[v],u});}typedef int ds[N];ds d,p,r,l,son,y;void dfs1(int u){ r[u]=1; d[u]=d[p[u]]+1; int s=0; for(edge* i=h[u];i;i=i->s) if(i->v!=p[u]){ p[i->v]=u; dfs1(i->v); r[u]+=r[i->v]; if(s<r[i->v]) s=r[son[u]=i->v]; }}void dfs2(int u){ static int j; l[u]=++j; if(r[u]!=1){ y[son[u]]=y[u]; dfs2(son[u]); } for(edge* i=h[u];i;i=i->s) if(i->v!=p[u] &&i->v!=son[u]) dfs2(y[i->v]=i->v);}int lca(int s,int t){ while(y[s]^y[t]) d[y[s]]<d[y[t]]? (s^=t,t^=s,s^=t) :0,s=p[y[s]]; return d[s]<d[t]?s:t;}struct node{ int v,s,a,q; node *l,*r; void up(){ s=l->s+r->s+a; }}*f[N],e[N*40];node* back=e+1;node* create(int v){ return &(*back++ =(node){v, 1,1,rand(),e,e});}void lturn(node*& s){ node* a=s->r; s->r=a->l; s->up(),a->l=s; a->up(),s=a;}void rturn(node*& s){ node* a=s->l; s->l=a->r; s->up(),a->r=s; a->up(),s=a;}void ins(int v,node*& s){ if(!s->s) s=create(v); IF(v==s->v) ++s->a,s->up(); IF(v<s->v){ ins(v,s->l); if(s->l->q>s->q) rturn(s); else s->up(); }else{ ins(v,s->r); if(s->r->q>s->q) lturn(s); else s->up(); }}void del(int v,node*& s){ if(v<s->v) del(v,s->l),s->up(); IF(s->v<v) del(v,s->r),s->up(); IF(s->a>1) --s->a,s->up(); IF(s->l==e)s=s->r; IF(s->r==e)s=s->l; IF(s->l->q>s->r->q) rturn(s), del(v,s->r),s->up(); else lturn(s), del(v,s->l),s->up();}int query(int v,node* s){ int k=0; while(s->s) if(v<s->v)s=s->l; else k+=s->l->s +s->a,s=s->r; return k;}int query(int i,int j){ for(int k=0;;i^=i&-i){ if(!i)return k; k+=query(j,f[i]); }}void ins1(int i,int j){ for(;i<=n;i+=i&-i) ins(j,f[i]);}void ins2(int s,int t){ if(l[s]<l[t]) s^=t,t^=s,s^=t; ins1(l[t],l[s]);}void del1(int i,int j){ for(;i<=n;i+=i&-i) del(j,f[i]);}void del2(int s,int t){ if(l[s]<l[t]) s^=t,t^=s,s^=t; del1(l[t],l[s]);}int query(int i,int j,int s,int t){ return query(j,t) -query(j,s-1) -query(i-1,t) +query(i-1,s-1);}int find(int s,int t){ static int j; for(;y[s]^y[t];s=p[j]) j=y[s]; return s^t?son[t]:j;}int qtree(int s,int t){ if(d[s]<d[t]) s^=t,t^=s,s^=t; static int i,j,k; i=l[s],j=l[s]+r[s]-1; if(lca(s,t)!=t) return l[s]<l[t] ?query(i,j, l[t],l[t]+r[t]-1) :query(l[t], l[t]+r[t]-1,i,j); k=find(s,t); return(l[k]+r[k]>n?0 :query(i,j,l[k]+r[k],n)) +query(1,l[k]-1,i,j);}int main(){ struct{ operator int(){ int x; scanf("%d",&x); return x; } }it; n=it; for(int i=0;i<=n;++i) f[i]=e; for(int i=1;i!=n;++i) add(it,it); dfs1(1),dfs2(y[1]=1); for(m=it;m;--m) ins2(it,it); for(q=it;q;--q){ int k=it,s=it,t=it; if(k==3) printf("%d\n", qtree(s,t)); if(k==1)ins2(s,t); if(k==2)del2(s,t); }}
bzoj4285: 使者
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。