标签:
搞出dfs序,转化为查询矩形点数,树套树搞定。
#include<cstdio> #include<cstdlib> #define N 100005 #define IF else if struct 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); } }
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5864502.html