【Splay模板】

2 篇文章 0 订阅
1 篇文章 0 订阅

Splay

其实是个十分神奇的东西——

具体来说呢,就是二叉搜索树的优化,使得它的最坏情况(一条链)消除

再具体一点呢。。。百度百科

这里推荐 yyb ,因为笔者觉得他的博客是我见过博客中写的比较清晰的,常数也是很小的,且笔者也是在他博客中弄懂 Splay 的,希望大家能够有所收获。
Tips:完整代码可以在我这篇文章里看,还有打完板子之后可以在这里评测。

在此附上完整代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define RG register
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;

inline int gi(){
    int data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0'&&ch<='9') data=data*10+ch-'0',ch=getchar();
    return data*w;
}

#define N 500010

int root,total; 
struct node{
    int ch[2],cnt,size,fa,val;
}t[N];

int get(int x){
    return t[t[x].fa].ch[1]==x;
}

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

void rotate(int x){
    int y=t[x].fa;int z=t[y].fa;
    int which=get(x);
    t[z].ch[get(y)]=x;
    t[x].fa=z;
    t[y].ch[which]=t[x].ch[which^1];
    t[t[x].ch[which^1]].fa=y;
    t[x].ch[which^1]=y;
    t[y].fa=x;
    pushup(y);pushup(x);
}

void splay(int x,int goal){
    while(t[x].fa!=goal){
        int y=t[x].fa,z=t[y].fa;
        if(z!=goal)
            get(x)^get(y)?rotate(x):rotate(y);
        rotate(x);
    }
    if(goal==0) root=x;
}

inline void find(int x){
    int u=root;
    if(!u) return ;
    while(t[u].ch[x>t[u].val]&&x!=t[u].val) {
        u=t[u].ch[x>t[u].val];
    }
    splay(u,0);
}

void insert(int x){
    int u=root,fa=0;
    while(u&&t[u].val!=x){
        fa=u;
        u=t[u].ch[x>t[u].val];
    }
    if(u) t[u].cnt++;
    else{
        total++;
        u=total;
        if(fa) t[fa].ch[x>t[fa].val]=u;
        t[u].ch[0]=t[u].ch[1]=0;
        t[total].fa=fa;
        t[total].val=x;
        t[total].cnt=1;
        t[total].size=1;
    }
    splay(u,0);
}

int NEXT(int x,int f){
    find(x);
    int u=root;
    if(t[u].val>x&&f) return u;
    if(t[u].val<x&&!f) return u;
    u=t[u].ch[f];
    while(t[u].ch[f^1]) u=t[u].ch[f^1];
    return u;
}

void Delete(int x){
    int last=NEXT(x,0);
    int next=NEXT(x,1);
    splay(last,0);splay(next,last);
    int del=t[next].ch[0];
    if(t[del].cnt>1){
        t[del].cnt--;
        splay(del,0);
    }
    else t[next].ch[0]=0;
}

int Rank(int x){
    int u=root;
    if(t[u].size<x) return 0;
    while(true){
        int y=t[u].ch[0];
        if(x>t[y].size+t[u].cnt){
            x-=t[y].size+t[u].cnt;
            u=t[u].ch[1];
        }
        else if(t[y].size>=x) u=y;
        else return t[u].val;
    }
}

int main(){
    RG int n=gi();
    insert( 2147483647);
    insert(-2147483647);

    while(n--){
        int opt=gi();

        if(opt==1){insert(gi());}
        if(opt==2){Delete(gi());}
        if(opt==3){find(gi());printf("%d\n",t[t[root].ch[0]].size);}
        if(opt==4){printf("%d\n",Rank(gi()+1));}
        if(opt==5){printf("%d\n",t[NEXT(gi(),0)].val);}
        if(opt==6){printf("%d\n",t[NEXT(gi(),1)].val);}

    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值