码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】Treap

时间:2018-11-10 17:56:55      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:shu   ==   旋转   通过   mes   max   int   treap   现在   

Treap,又称树堆,是一种通过堆性质来维持BST平衡的数据结构。具体体现在对于树上每一个点来说,既有BST维护的值,又有一个堆维护的随机生成的值。维护平衡性的办法是根据堆维护的值的相对大小关系进行左旋和右旋这两种操作,在旋转的前后,依然满足BST性质

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

int ans;
struct node{int lc,rc,val,cnt,size,rd;};
struct Treap{
    #define ls t[x].lc
    #define rs t[x].rc
    node t[maxn];
    int root,tot;
    Treap():root(0),tot(0){}
    ~Treap(){}
    inline int newnode(int val){
        ++tot,t[tot].size=t[tot].cnt=1,t[tot].val=val,t[tot].rd=rand();
        return tot;
    }
    inline void pushup(int x){
        t[x].size=t[ls].size+t[rs].size+t[x].cnt;
    }
    inline void zig(int &x){
        int lson=ls;
        ls=t[lson].rc,t[lson].rc=x,x=lson;
        pushup(t[lson].rc),pushup(x);
    }
    inline void zag(int &x){
        int rson=rs;
        rs=t[rson].lc,t[rson].lc=x,x=rson;
        pushup(t[rson].lc),pushup(x);
    }
    void insert(int &x,int val){
        if(!x)x=newnode(val);
        else if(val==t[x].val)++t[x].cnt,++t[x].size;
        else if(val<t[x].val){
            ++t[x].size,insert(ls,val);
            if(t[ls].rd<t[x].rd)zig(x);
        }else{
            ++t[x].size,insert(rs,val);
            if(t[rs].rd<t[x].rd)zag(x);
        }
    }
    void del(int &x,int val){
        if(!x)return;
        else if(val==t[x].val){
            if(t[x].cnt>1)--t[x].cnt,--t[x].size;
            else if(!ls||!rs)x=ls+rs;
            else if(t[ls].rd<t[rs].rd)zig(x),del(x,val);
            else zag(x),del(x,val);
        }
        else if(val<t[x].val)--t[x].size,del(ls,val);
        else --t[x].size,del(rs,val);
    }
    int getrank(int x,int val){
        if(val<t[x].val)return getrank(ls,val);
        else if(val>t[x].val)return getrank(rs,val)+t[ls].size+t[x].cnt;
        else return t[ls].size+1;
    }
    int kth(int x,int k){
        if(k<=t[ls].size)return kth(ls,k);
        else if(k>t[ls].size+t[x].cnt)return kth(rs,k-t[ls].size-t[x].cnt);
        else return t[x].val;
    }
    void pre(int x,int val){
        if(!x)return;
        else if(t[x].val<val)ans=t[x].val,pre(rs,val);
        else pre(ls,val);
    }
    void nxt(int x,int val){
        if(!x)return;
        else if(t[x].val>val)ans=t[x].val,nxt(ls,val);
        else nxt(rs,val);
    }
}treap;

int main(){
    int n;scanf("%d",&n);
    while(n--){
        int opt,val;scanf("%d%d",&opt,&val);
        switch(opt){
            case 1:treap.insert(treap.root,val);break;
            case 2:treap.del(treap.root,val);break;
            case 3:printf("%d\n",treap.getrank(treap.root,val));break;
            case 4:printf("%d\n",treap.kth(treap.root,val));break;
            case 5:treap.pre(treap.root,val);printf("%d\n",ans);break;
            case 6:treap.nxt(treap.root,val);printf("%d\n",ans);break;
        }
    }
    return 0;
}

【模板】Treap

标签:shu   ==   旋转   通过   mes   max   int   treap   现在   

原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9939823.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!