bzoj 3224(非旋转treap)

本文详细介绍了非旋转Treap的数据结构特点及其实现方法。非旋转Treap相比普通Treap速度较慢,但比Splay快,并且能够实现如区间翻转等Splay和其他平衡树无法实现的操作。文中提供了具体的C++实现代码示例,包括插入、删除、查找等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门
附上两篇讲解:
http://www.cnblogs.com/nietzsche-oier/p/6748292.html
http://blog.youkuaiyun.com/zmh964685331/article/details/50536410
P.S.非旋转treap比普通treap慢,比splay快,可以实现splay能实现的而其余平衡树无法实现的操作比如区间翻转。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define mp(x,y) make_pair(x,y)
const int MAXN=1e5+4;
typedef pair<int ,int > pii;
struct Node {
    int lc,rc,val,key,siz;
}t[MAXN];
int n,x,root,cnt,opt;
inline void update(int rt) {
    t[rt].siz=t[t[rt].lc].siz+t[t[rt].rc].siz+1;
}
pii split(int a,int n) {
    if (!n) return mp(0,a);
    int lc(t[a].lc),rc(t[a].rc);
    if (n==t[lc].siz) return t[a].lc=0,update(a),mp(lc,a);
    if (n==t[lc].siz+1) return t[a].rc=0,update(a),mp(a,rc);
    if (n<t[lc].siz) {
        pii tmp=split(lc,n);
        t[a].lc=tmp.second,update(a);
        return mp(tmp.first,a);
    }
    pii tmp=split(rc,n-t[lc].siz-1);
    t[a].rc=tmp.first,update(a);
    return mp(a,tmp.second);
}
int merge(int a,int b) {
    if (!a||!b) return a+b;
    if (t[a].key<t[b].key) return t[a].rc=merge(t[a].rc,b),update(a),a;
    else return t[b].lc=merge(a,t[b].lc),update(b),b;
}
int rank(int x,int rt) {//x的排名
    int ret=0,tmp=1e9;
    while (rt) {
        if (x==t[rt].val) tmp=min(tmp,ret+t[t[rt].lc].siz+1);
        if (x>t[rt].val) ret+=t[t[rt].lc].siz+1,rt=t[rt].rc;
        else rt=t[rt].lc;
    }
    return tmp==(int)1e9?ret:tmp;
}
int find(int x,int rt) {
    while (true) {
        if (t[t[rt].lc].siz==x-1) return t[rt].val;
        if (t[t[rt].lc].siz>x-1) rt=t[rt].lc;
        else x-=t[t[rt].lc].siz+1,rt=t[rt].rc;
    }
}
int pre(int x,int rt) {
    int ret=-1e9;
    while (rt) {
        if (x>t[rt].val) ret=max(ret,t[rt].val),rt=t[rt].rc;
        else rt=t[rt].lc;
    }
    return ret;
}
int nxt(int x,int rt) {
    int ret=1e9;
    while (rt) {
        if (x<t[rt].val) ret=min(ret,t[rt].val),rt=t[rt].lc;
        else rt=t[rt].rc;
    }
    return ret;
}
inline void Insert(int x) {
    int k=rank(x,root);
    pii tmp=split(root,k);
    t[++cnt].val=x;
    t[cnt].key=rand();
    t[cnt].siz=1;
    root=merge(tmp.first,cnt);
    root=merge(root,tmp.second);
}
inline void del(int x){
    int k=rank(x,root);
    pii t1=split(root,k);
    pii t2=split(t1.first,k-1);
    root=merge(t2.first,t1.second);
}
int main() {
//  freopen("bzoj 3224.in","r",stdin);
    scanf("%d",&n);
    for (register int i=0;i<n;++i) {
        scanf("%d%d",&opt,&x);
        switch (opt) {
            case 1:Insert(x);break;
            case 2:del(x);break;
            case 3:printf("%d\n",rank(x,root));break;
            case 4:printf("%d\n",find(x,root));break;
            case 5:printf("%d\n",pre(x,root));break;
            case 6:printf("%d\n",nxt(x,root));break;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值