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

没啥好说的。
唯一要注意的是,每次操作后有了修改一定要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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值