1. 程式人生 > >【平衡樹】2018國慶三校聯考D3T3

【平衡樹】2018國慶三校聯考D3T3

在這裡插入圖片描述


分析:

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<assert.h>
#define SF scanf
#define PF printf
#define MAXN 200010
#define MOD 1000000009
using namespace std;
typedef long long ll;
struct node *NIL;
struct node{
    node *ch[2
],*fa; int val,siz; bool Dir(){ return this==fa->ch[1]; } void setchild(node *x,int d){ ch[d]=x; if(x!=NIL) x->fa=this; } void pushup(){ siz=ch[0]->siz+ch[1]->siz+1; } }tree[MAXN*2]; int fax[MAXN]; node *lc[MAXN],*rc[
MAXN]; node * Newnode(node *x,int val){ x->ch[0]=x->ch[1]=x->fa=NIL; x->val=val; x->siz=1; return x; } void Rotate(node *x){ node *y=x->fa; int d=x->Dir(); if(y->fa==NIL) x->fa=NIL; else y->fa->setchild(x,y->Dir()); y-
>setchild(x->ch[!d],d); x->setchild(y,!d); y->pushup(); } void Splay(node *x,node *rt){ while(x->fa!=rt){ node *y=x->fa; if(y->fa==rt){ Rotate(x); break; } if(x->Dir()==y->Dir()) Rotate(y); else Rotate(x); Rotate(x); } x->pushup(); } node *find_nxt(node *x,int d){ while(x->ch[d]!=NIL) x=x->ch[d]; return x; } int check(int a,int b){ Splay(lc[a],NIL); node *rta=find_nxt(lc[a],0); Splay(rta,NIL); Splay(lc[b],NIL); node *rtb=find_nxt(lc[b],0); Splay(rtb,NIL); if(rta!=rtb) return 0; Splay(lc[a],NIL); int siz1=lc[a]->ch[0]->siz; Splay(rc[a],NIL); int siz2=rc[a]->ch[0]->siz; Splay(lc[b],NIL); int siz=lc[b]->ch[0]->siz; if(siz1<siz&&siz<siz2) return 1; if(fax[rta->val]!=0){ node *x=lc[fax[rta->val]]; Splay(x,NIL); int sizx=x->ch[0]->siz; if(siz1<=sizx&&sizx<=siz2) return 1; } return 0; } void cut(int x){ node *a=lc[x]; node *b=rc[x]; Splay(a,NIL); if(a->ch[0]==NIL){ fax[x]=0; return ; } node *rt=find_nxt(a,0); Splay(rt,NIL); if(fax[rt->val]==0||check(x,fax[rt->val])==0){ Splay(rt,NIL); Splay(a,rt); Splay(b,a); node *t=find_nxt(b->ch[1],0); Splay(t,b); rt->setchild(t,1); t->setchild(a->ch[0],0); a->fa=NIL; a->ch[0]=NIL; b->ch[1]=NIL; t->pushup(); rt->pushup(); b->pushup(); a->pushup();//cut a from x } else{ node *c=lc[fax[rt->val]]; fax[rt->val]=0; assert(rt->ch[0]==NIL); Splay(rt,NIL); Splay(a,rt); Splay(b,a); node *t=find_nxt(b->ch[1],0); Splay(t,b); rt->setchild(t,1); t->setchild(a->ch[0],0); a->fa=NIL; a->ch[0]=NIL; b->ch[1]=NIL; t->pushup(); rt->pushup(); b->pushup(); a->pushup();//cut a from x //PF("{%d %d}\n",a->ch[0]-tree,a->ch[1]-tree); Splay(c,NIL); node *d=find_nxt(c->ch[1],0); Splay(d,c); d->setchild(rt,0); d->pushup(); c->pushup(); } } void link(int a,int b){ Splay(lc[a],NIL); assert(lc[a]->ch[0]==NIL); if(check(a,b)||a==b){//we can reach a from b fax[a]=b; } else{ Splay(lc[a],NIL); node *c=lc[b]; Splay(c,NIL); node *d=find_nxt(c->ch[1],0); Splay(d,c); d->setchild(lc[a],0); d->pushup(); c->pushup(); } } int n,m; int main(){ freopen("repeater.in","r",stdin); freopen("repeater.out","w",stdout); int tag,a,b; NIL=&tree[0]; NIL->ch[0]=NIL->ch[1]=NIL->fa=NIL; SF("%d%d",&n,&m); for(int i=1;i<=n;i++){ lc[i]=Newnode(&tree[i],i); rc[i]=Newnode(&tree[i+n],i); lc[i]->setchild(rc[i],1); } ll ans=0; int cnt=0; for(int i=1;i<=m;i++){ //PF("[now,begin %d]:\n",i); SF("%d%d%d",&tag,&a,&b); if(tag==1){ cut(a); if(b!=0) link(a,b); } else{ //PF("{%d}\n",check(b,a)); ans=(ans*2ll+check(b,a))%MOD; } /*for(int i=1;i<=n;i++){ PF("fa:(%d)",fax[i]); PF("<%d,(%d),%d> | <%d,(%d),%d>\n",lc[i]->ch[0]-tree,lc[i]-tree,lc[i]->ch[1]-tree,rc[i]->ch[0]-tree,rc[i]-tree,rc[i]->ch[1]-tree); }*/ } PF("%lld",ans); }