1、Splay

(Tyvj1728)

#include <bits/stdc++.h>

using namespace std;
const int MAXN=1e5+10,INF=1<<30;
int n,op,x,root,ch[MAXN][2],sz[MAXN],cnt[MAXN],val[MAXN],f[MAXN],tot=0;

void pushup(int x)
{sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];}

void Rotate(int x)
{
    int y=f[x],z=f[y],k=(x==ch[y][1]);
    ch[z][y==ch[z][1]]=x;f[x]=z;
    ch[y][k]=ch[x][k^1];f[ch[x][k^1]]=y;
    ch[x][k^1]=y;f[y]=x;
    pushup(x);pushup(y);
}

void Splay(int x,int up)
{
    while(f[x]!=up)
    {
        int y=f[x],z=f[y];
        if(z!=up) (ch[y][0]==x)^(ch[z][0]==y)?Rotate(x):Rotate(y);
        Rotate(x);
    }
    if(!up) root=x;
}

void Insert(int x)
{
    int k=root,anc=0;
    while(k&&x!=val[k])
        anc=k,k=ch[k][x>val[k]];
    
    if(k) cnt[k]++;
    else
    {
        k=++tot;
        if(anc) ch[anc][x>val[anc]]=k;
        ch[k][0]=ch[k][1]=0;
        val[k]=x;cnt[k]=1;sz[k]=1;f[k]=anc;
    }
    Splay(k,0);
}

void Find(int x)
{
    int k=root;
    if(!k) return;
    while(ch[k][x>val[k]]&&x!=val[k])
        k=ch[k][x>val[k]];
    Splay(k,0);
}

int Next(int x,int flag)
{
    Find(x);
    int k=root;
    if((val[k]<x&&!flag)||(val[k]>x&&flag)) return k;
    
    k=ch[k][flag];
    while(ch[k][flag^1]) k=ch[k][flag^1];
    
    return k;
}

int Kth(int x)
{
    int k=root;
    if(sz[k]<x) return 0;
    while(true)
    {
        if(x>sz[ch[k][0]]+cnt[k])
            x-=sz[ch[k][0]]+cnt[k],k=ch[k][1];
        else if(sz[ch[k][0]]>=x)
            k=ch[k][0];
        else return val[k];
    }
}

void Delete(int x)
{
    int lst=Next(x,0),nxt=Next(x,1);
    Splay(lst,0);Splay(nxt,lst);
    
    if(cnt[ch[nxt][0]]>1)
        cnt[ch[nxt][0]]--,Splay(ch[nxt][0],0);
    else ch[nxt][0]=0;
}

int main()
{
    scanf("%d",&n);
    Insert(INF);Insert(-INF);//记得先插入边界 
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&op,&x);
        if(op==1) Insert(x);
        else if(op==2) Delete(x);
        else if(op==3) Find(x),printf("%d\n",sz[ch[root][0]]);
        else if(op==4) printf("%d\n",Kth(x+1));
        else if(op==5) printf("%d\n",val[Next(x,0)]);
        else if(op==6) printf("%d\n",val[Next(x,1)]);
    }
    return 0;
}
Splay

相关文章: