模板——Splay

$Splay$

#include <bits/stdc++.h>
using namespace std;
const int inf=2*1e8+100;
int n,root,t;
struct node
{
    int sf,son[2],si,va,fa,g;
}sh[110000];
int newcode()
{
    ++t;
    return t;
}
void pushup(int x)
{
    sh[x].si=sh[x].g+sh[sh[x].son[0]].si+sh[sh[x].son[1]].si;
}
void connect(int x,int y,int s)
{
    sh[y].son[s]=x;
    sh[x].sf=s;
    sh[x].fa=y;
}
void clear()
{
    sh[0].fa=sh[0].g=sh[0].sf=sh[0].si=sh[0].va=0;
    memset(sh[0].son,0,sizeof(sh[0].son));
}
void rotate(int x)
{
    int sf,fa,y,z,s;
    s=sh[x].sf;
    z=sh[x].son[sh[x].sf^1];
    sf=sh[sh[x].fa].sf;
    fa=sh[sh[x].fa].fa;
    y=sh[x].fa;
    connect(x,fa,sf);
    connect(y,x,s^1);
    connect(z,y,s);
    clear();
    pushup(y);
    pushup(x);
}
void splay(int x,int y)
{
    while (sh[x].fa!=y)
    {
        if (sh[sh[x].fa].fa==y)
          rotate(x);
        else
        if (sh[sh[x].fa].sf==sh[x].sf)
        {
            rotate(sh[x].fa);
            rotate(x);
        }
        else
        {
            rotate(x);
            rotate(x);
        }
    }
    if (y==0)
      root=x;
}
void insert(int v)
{
    if (root==-1)
    {
        sh[newcode()].va=v;
        sh[t].si=sh[t].g=1;
        root=t;
        return;
    }
    int cur;
    cur=root;
    while (sh[cur].son[v>sh[cur].va]!=0 && sh[cur].va!=v)
      cur=sh[cur].son[v>sh[cur].va];
    if (sh[cur].va==v)
    {
        sh[cur].g++;
        pushup(cur);
        splay(cur,0);
    }
    else
    {
        if (v>sh[cur].va)
        {
            connect(newcode(),cur,1);
        }
        else
        {
            connect(newcode(),cur,0);
        }
        sh[t].va=v;
        sh[t].si=sh[t].g=1;
        pushup(cur);
        splay(t,0);
    }
}
void find(int v)
{
    int cur;
    cur=root;
    while (sh[cur].son[v>sh[cur].va]!=0 && sh[cur].va!=v)
      cur=sh[cur].son[v>sh[cur].va];
    splay(cur,0);
}
int per(int v)
{
    find(v);
    int cur;
    if (sh[root].va<v)
      return root;
    cur=sh[root].son[0];
    while (sh[cur].son[1]!=0)
      cur=sh[cur].son[1];
    return cur;
}
int succ(int v)
{
    find(v);
    int cur;
    if (sh[root].va>v)
      return root;
    cur=sh[root].son[1];
    while (sh[cur].son[0]!=0)
      cur=sh[cur].son[0];
    return cur;
}
void del(int v)
{
    int p,s;
    p=per(v);
    s=succ(v);
    splay(p,0);
    splay(s,p);
    int cur;
    cur=sh[s].son[0];
    sh[cur].g--;
    if (sh[cur].g==0)
    {
        sh[s].son[0]=0;
        sh[cur].fa=0;
        pushup(cur);
        pushup(s);
        pushup(p);
    }
    else
      splay(cur,0);
}
int rank(int x)
{
    find(x);
    return sh[sh[root].son[0]].si;
}
int kth(int k)
{
    int cur;
    cur=root;
    while (k!=0)
    {
        clear();
        if (sh[sh[cur].son[0]].si<k && k<=sh[sh[cur].son[0]].si+sh[cur].g)
          return sh[cur].va;
        else
        if (k<sh[sh[cur].son[0]].si+sh[cur].g)
          cur=sh[cur].son[0];
        else
        {
            k-=sh[sh[cur].son[0]].si+sh[cur].g;
            cur=sh[cur].son[1];
        }
    }
    return sh[cur].va;
}
int main()
{
    root=-1;
    insert(inf);
    insert(-inf);
    scanf("%d",&n);
    for (int i=1;i<=n;++i)
    {
        int op,x;
        scanf("%d%d",&op,&x);
        if (op==1)
          insert(x);
        else
        if (op==2)
          del(x);
        else
        if (op==3)
          printf("%d\n",rank(x));
        else
        if (op==4)
          printf("%d\n",kth(x+1));
        else
        if (op==5)
          printf("%d\n",sh[per(x)].va);
        else
        if (op==6)
          printf("%d\n",sh[succ(x)].va);
    }
}

 

转载于:https://www.cnblogs.com/huangchenyan/p/11216762.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值