[学习笔记] bzoj3224 普通平衡树:splay模板

来源:互联网 发布:台湾服饰品牌知乎 编辑:程序博客网 时间:2024/06/07 05:26

没啥好说的。
唯一要注意的是,每次操作后有了修改一定要splay!

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<climits>#include<assert.h>#define N 110000#define INF INT_MAX#define inf INT_MIN#define debug(x) cerr<<#x<<"="<<x#define sp <<" "#define ln <<endl#define pause system("pause")#define A(x) assert(x)using namespace std;int val[N],fa[N],ncnt,ch[N][2],sz[N],cnt[N];struct Splay{    int rt,infp,INFp;    Splay()    {        infp=insert(inf),sz[infp]=cnt[infp]=0;        INFp=insert(INF),sz[INFp]=cnt[INFp]=0;    }    inline int gw(int x)    {  return ch[fa[x]][1]==x;  }    inline int new_node(int v)    {        int x=++ncnt;fa[x]=ch[x][0]=ch[x][1]=0;        val[x]=v,sz[x]=cnt[x]=1;return x;    }    inline int push_up(int x)    {        return sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];    }    inline int setch(int x,int y,int w)    {        if(!x) return fa[rt=y]=0;if(y) fa[y]=x;        return ch[x][w]=y,push_up(x);    }    inline int rotate(int x)    {        int y=fa[x],z=fa[y],a=gw(x),b=gw(y),c=ch[x][a^1];        return setch(y,c,a),setch(x,y,a^1),setch(z,x,b);    }    inline int splay(int x,int tar=0)    {        while(fa[x]^tar)        {            if(fa[fa[x]]^tar)                if(gw(x)^gw(fa[x])) rotate(x);                else rotate(fa[x]);            rotate(x);        }        return x;    }    inline int insert(int v)    {        int p=rt,last=0;        while(p)        {            last=p;            if(v<val[p]) p=ch[p][0];            else if(v==val[p]) break;            else p=ch[p][1];        }        if(p) cnt[p]++,sz[p]++;        else setch(last,p=new_node(v),v>val[last]);        return splay(p);    }    inline int find(int v)//find(value)=>position, lower_bound    {        int p=rt,x;        while(p)            if(v<=val[p]) p=ch[x=p][0];            else p=ch[p][1];        return splay(x);    }    inline int pre(int v)//pre(value)=>position, seriously smaller    {        int x=find(v),y=ch[x][0];        while(ch[y][1]) y=ch[y][1];        return splay(y);    }    inline int post(int v)//post(value)=>position, upper_bound    {        int x=find(v),y=ch[x][1];        if(v^val[x]) return x;        while(ch[y][0]) y=ch[y][0];        return splay(y);    }    inline int del(int v)//del(value)    {        int x=rt;        while(x)            if(v<val[x]) x=ch[x][0];            else if(v==val[x]) break;            else x=ch[x][1];        if(!x) return 0;        cnt[x]--,sz[x]--,splay(x);        if(!cnt[x])        {            int y=ch[x][0],z=ch[x][1];            while(ch[y][1]) y=ch[y][1];            while(ch[z][0]) z=ch[z][0];            splay(y),splay(z,y),setch(z,0,0),fa[x]=0,push_up(y);        }        return 0;    }    inline int kth(int k)//getk(k)=>position    {        int p=rt,s;        while(p)            if(k<=(s=sz[ch[p][0]])) p=ch[p][0];            else if((k-=s+cnt[p])<=0) return splay(p);            else p=ch[p][1];        return splay(p);    }    inline int rank(int v)//rank(value)=>size    {        int x=find(v);splay(x);        return sz[ch[x][0]]+(val[x]==v);    }}s;int main(){    int q;scanf("%d",&q);    while(q--)    {        int opt,x;scanf("%d%d",&opt,&x);        if(opt==1) s.insert(x);        else if(opt==2) s.del(x);        else if(opt==3) printf("%d\n",s.rank(x));        else if(opt==4) printf("%d\n",val[s.kth(x)]);        else if(opt==5) printf("%d\n",val[s.pre(x)]);        else printf("%d\n",val[s.post(x)]);    }    return 0;}
原创粉丝点击