(新知)数据结构--Treap--模版

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <ctime>

using namespace std;

struct Node {
    int key,fix,cnt,siz; //multi
    Node* ch[2];

    Node() {}
    Node(int);
    int dir(int _) {
        if(_==key) return -1;
        else return _<key?0:1;
    }
    void maintain() {
        siz=ch[0]->siz+ch[1]->siz+cnt;
        return;
    }
}*null,*root;

void init_null() {
    null=new Node();
    null->fix=rand();
    null->ch[0]=null->ch[1]=null;
    null->siz=null->cnt=0;
    null->key=20000722;
    root=null;
    return;
}

Node:: Node(int _): key(_) {
    siz=cnt=1;
    fix=rand();
    ch[0]=ch[1]=null;
}

void print(Node* cur) {
    if(cur==null) return;
    print(cur->ch[0]);
    for(int i=1;i<=cur->cnt;i++) printf("%d ",cur->key);
    print(cur->ch[1]);
    return;
}

void Rotate(Node* &cur,int dir) {
    Node *tmp=cur->ch[dir^1];
    cur->ch[dir^1]=tmp->ch[dir];
    tmp->ch[dir]=cur;
    cur->maintain(),tmp->maintain();
    cur=tmp;
    return;
}

void treap_ins(Node* &cur,int new_key) {
    if(cur==null) {
        cur=new Node(new_key);
        return;
    }
    int dir=cur->dir(new_key);
    if(!~dir) {
        cur->cnt++;
        cur->maintain();
        return;
    }
    else {
        treap_ins(cur->ch[dir],new_key);
        if(cur->fix>cur->ch[dir]->fix) Rotate(cur,dir^1);
        cur->maintain();
        return;
    }
    return;
}

void treap_del(Node* &cur,int del_key) {
    if(cur==null) return;
    int dir=cur->dir(del_key);
    if(!~dir) {
        Node* tmp=cur;
        if(cur->cnt>1) {
            cur->cnt--;
            cur->maintain();
            return;
        }
        else if(cur->ch[0]==null) {
            cur=cur->ch[1];
            delete tmp;
            tmp=null;
        }
        else if(cur->ch[1]==null) {
            cur=cur->ch[0];
            delete tmp;
            tmp=null;
        }
        else {
            int dir2=cur->ch[0]->fix>cur->ch[1]->fix?1:0;
            Rotate(cur,dir2^1);
            treap_del(cur->ch[dir2^1],del_key);
        }
    }
    else treap_del(cur->ch[dir],del_key);
    cur->maintain();
    return;
}

int k_th(Node* cur,int k) {
    int num=cur->cnt+cur->ch[0]->siz;
    if(k>num)
        return k_th(cur->ch[1],k-num);
    else if(k<=cur->ch[0]->siz)
        return k_th(cur->ch[0],k);
    else
        return cur->key;
}

int k_rank(Node* cur,int k) {
    if(cur->key==k) return cur->ch[0]->siz;
    else if(cur->key<k) return cur->ch[0]->siz+cur->cnt+k_rank(cur->ch[1],k);
    else return k_rank(cur->ch[0],k);
}

inline int findpre(Node* cur,int key) {
    if(cur==null) return -int(1e9);
    if(key<cur->key) return findpre(cur->ch[0],key);
    else if(key==cur->key) return key;
    else return max(cur->key,findpre(cur->ch[1],key));
}

inline int findnext(Node* cur, int key) {
    if(cur==null) return int(1e9);
    if(key<cur->key) return min(cur->key,findnext(cur->ch[0],key));
    else if(key==cur->key) return key;
    else return findnext(cur->ch[1],key);
}

const int maxn=int(1e4)+20;
int n,m;
int add[maxn];
int que[maxn],pt=1;

int main() {

    srand(time(0));
    init_null();

    char op[10];
    while(scanf("%s",op)!=EOF) {
        if(op[0]=='i') {
            int new_key;
            scanf("%d",&new_key);
            treap_ins(root,new_key);
        }
        else if(op[0]=='p' && op[2]=='i') {
            print(root);
            putchar('\n');
            continue;
        }
        else if(op[0]=='d') {
            int del_key;
            scanf("%d",&del_key);
            treap_del(root,del_key);
        }
        else if(op[0]=='k') {
            int k;
            scanf("%d",&k);
            if(k==1) {
                cout<<"root::key:"<<root->key<<endl;
            }
            printf("%d\n",k_th(root,k));
        }
        else if(op[0]=='r') {
            int k;
            scanf("%d",&k);
            cout<<k_rank(root,k)+1<<endl;
        }
        else if(op[0]=='p') {
            int k;
            scanf("%d",&k);
            cout<<findpre(root,k)<<endl;
        }
        else if(op[0]=='n') {
            int k;
            scanf("%d",&k);
            cout<<findnext(root,k)<<endl;
        }
        else if(op[0]=='e') {
            return 0;
        }
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值