3224: Tyvj 1728 普通平衡树

来源:互联网 发布:复旦cpu卡算法 编辑:程序博客网 时间:2024/06/18 13:39

终于想起来我今天干嘛了。

没错,我要写替罪羊树啊。

然后发现已经到晚上了 〒▽〒 简直不像话

数落一下发现今天学到的都好奇怪(。・・)ノ我的天我今天到底在干嘛。

于是还是水(抄)了一发替罪羊树。

写完之后感觉我整个人都要拍扁重建了。

不造为什么我的替罪羊树跑得木有SBT快,不科学啊。

#include<iostream>#include<cstdio>#include<cstring>#include<cctype>using namespace std;template<class T>void read(T &x){static char c;static bool f;for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1;for(x=0;isdigit(c);c=getchar())x=x*10+c-'0';if(f)x=-x;}const int N=200000+10;const double alpha=0.75;struct Node{Node *ch[2];int sz,v,cnt;bool ex;bool scapegoat(){return ch[0]->cnt>alpha*cnt+5||ch[1]->cnt>alpha*cnt+5;}void pushup(){sz=ch[0]->sz+ch[1]->sz+ex;cnt=ch[0]->cnt+ch[1]->cnt+1;}};struct ScapegoatTree{Node pool[N];Node *tail,*root,*null;Node *bc[N];Node *v[N];int bc_top,top;void init(){tail=pool;null=tail++;null->ch[0]=null->ch[1]=null;null->sz=null->v=null->cnt=0;root=null;bc_top=0;}Node *newnode(int v){Node *p;if(bc_top)p=bc[--bc_top];else p=++tail;p->ch[0]=p->ch[1]=null;p->v=v;p->sz=1;p->cnt=1;p->ex=true;return p;}void travel(Node *p){if(p==null)return;travel(p->ch[0]);if(p->ex)v[++top]=p;else bc[bc_top++]=p;travel(p->ch[1]);}Node *divide(int l,int r){if(l>r)return null;int mid=l+r>>1;Node *p=v[mid];p->ch[0]=divide(l,mid-1);p->ch[1]=divide(mid+1,r);p->pushup();return p;}void rebuild(Node *&p){top=0;travel(p);p=divide(1,top);}Node **insert(Node *&p,int val){if(p==null){p=newnode(val);return &null;}else{p->sz++;p->cnt++;int k=val>=p->v;Node **res=insert(p->ch[k],val);if(p->scapegoat())res=&p;return res;}}void insert(int val){Node **p=insert(root,val);if(*p!=null)rebuild(*p);}void erase(Node *p,int id){p->sz--;if(p->ex&&id==p->ch[0]->sz+1)p->ex=0;else{if(id<=p->ch[0]->sz+p->ex)erase(p->ch[0],id);else erase(p->ch[1],id-p->ch[0]->sz-p->ex);}}int rank(int val){Node *now=root;int ans=1;while(now!=null){if(now->v>=val)now=now->ch[0];else{ans+=now->ch[0]->sz+now->ex;now=now->ch[1];}}return ans;}int kth(int k){Node *now=root;while(now!=null){if(now->ex&&k==now->ch[0]->sz+1)return now->v;else if(k<=now->ch[0]->sz)now=now->ch[0];else{k-=now->ch[0]->sz+now->ex;now=now->ch[1];}}}void erase(int val){erase(root,rank(val));if(root->sz<alpha*root->cnt)rebuild(root);}int pre(int x){return kth(rank(x)-1);}int suc(int x){return kth(rank(x+1));}}sc;int main(){int n;read(n);int opt,x;sc.init();while(n--){read(opt);read(x);switch(opt){case 1:sc.insert(x);break;case 2:sc.erase(x);break;case 3:printf("%d\n",sc.rank(x));break;case 4:printf("%d\n",sc.kth(x));break;case 5:printf("%d\n",sc.pre(x));break;case 6:printf("%d\n",sc.suc(x));break;}}return 0;}


0 0
原创粉丝点击