bzoj 3224: Tyvj 1728 普通平衡树

来源:互联网 发布:淘宝支付宝账号怎么改 编辑:程序博客网 时间:2024/05/29 18:58

Splay 模版

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#include<vector>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+10,INF=1<<30;struct Node{    int v,sz;    Node *fa,*ch[2];    Node(int v=0):v(v){sz=1;ch[0]=ch[1]=fa=NULL;}    int cmp(int x) {return x==v?-1:x>v;}    void up() {        sz=1;        if(ch[0]!=NULL) sz+=ch[0]->sz;        if(ch[1]!=NULL) sz+=ch[1]->sz;    }}*pool[N*2];int top=0,n;void init() {for(int i=0;i<N;i++) pool[i]=new Node();}void newnode(Node* &p,int v,Node *fa){p=pool[top++]; *p=Node(v); p->fa=fa;}void del(Node* &p) {pool[--top]=p;p=NULL;}struct SplayTree{    Node *root;    inline int pd(Node *p){return p->fa->ch[1]==p;}    inline void rotate(Node* p)    {        int c=pd(p)^1;Node *t=p->fa;        t->ch[c^1]=p->ch[c];        if(p->ch[c])p->ch[c]->fa=t;        if((p->fa=t->fa)!=NULL) p->fa->ch[p->fa->ch[1]==t]=p;        t->fa=p;p->ch[c]=t;t->up();p->up();        if(p->fa==NULL) root=p;    }    inline void splay(Node* p,Node *FA)    {        for(;p->fa!=FA;rotate(p))            if(p->fa->fa!=FA) rotate(pd(p)==pd(p->fa)?p->fa:p);    }    void insert(Node* p,int val)    {        if(root==NULL){newnode(root,val,NULL);return ;}        Node *fa=NULL;        while(p!=NULL) fa=p,p=p->ch[val > p->v];        newnode(p,val,fa);fa->ch[val>fa->v]=p;        for(fa=p->fa;fa!=NULL;fa=fa->fa)             fa->up();        splay(p,NULL);    }    inline Node* find(Node *p,int val)    {        while(p!=NULL) {            int tcmp=p->cmp(val);            if(tcmp==-1) return p;            p=p->ch[tcmp];        }        return NULL;    }    Node* MAX(Node* p){        if(p==NULL) return NULL;        while(p->ch[1]!=NULL) p=p->ch[1];        return p;    }     Node* merge(Node* a,Node* b)    {        if(!b) return a;        if(!a) return b;        Node *t=MAX(a);        splay(t,NULL);        t->ch[1]=b;b->fa=t;t->up();        return t;    }    void remove(Node* p,int val)    {        Node* pos=find(root,val);        splay(pos,NULL);        pos=root;del(root);        root=merge(pos->ch[0],pos->ch[1]);        if(root!=NULL)root->fa=NULL;    }    inline int rank(Node* p,int val)    {        int ret=1;        while(p!=NULL){            int tcmp=val > p->v,d=p->ch[0]?p->ch[0]->sz:0;            if(tcmp) ret+=d+1; p=p->ch[tcmp];        }        return ret;    }    inline int kth(Node* p,int k)    {        while(p!=NULL){            int d=p->ch[0]?p->ch[0]->sz:0;            if(k==d+1) return p->v;            if(k<d+1) p=p->ch[0];            else k-=d+1,p=p->ch[1];        }        return -1;    }    inline int Pre(Node* p,int val)    {        int ret=-INF;        while(p!=NULL){            int tcmp=val > p->v;            if(tcmp) ret=max(ret,p->v);            p=p->ch[tcmp];        }        return ret;    }    inline int Sub(Node* p,int val)    {        int ret=INF;        while(p!=NULL){            int tcmp=val < p->v;            if(tcmp) ret=min(ret,p->v);            p=p->ch[tcmp^1];        }        return ret;    }    inline void insert(int x){insert(root,x);}    inline void remove(int x){remove(root,x);}    inline int rank(int x){return rank(root,x);}    inline int kth(int x){return kth(root,x);}    inline int Pre(int x){return Pre(root,x);}    inline int Sub(int x){return Sub(root,x);}}splay;int main(){    int op,x;    scanf("%d",&n);    init();    while(n--) {        scanf("%d%d",&op,&x);        if(op==1) splay.insert(x);        else if(op==2) splay.remove(x);        else if(op==3) printf("%d\n",splay.rank(x));        else if(op==4) printf("%d\n",splay.kth(x));        else if(op==5) printf("%d\n",splay.Pre(x));        else printf("%d\n",splay.Sub(x));    }    return 0;}
原创粉丝点击