bzoj3224: Tyvj 1728 普通平衡树 treap

题目链接“:3224: Tyvj 1728 普通平衡树

题解:treap平衡树模板 ,参考资料还有

#include<bits/stdc++.h>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define fi first
#define se second
#define PI 3.14159265
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define eps 1e-7
#define pii pair<int,int>
typedef unsigned long long ull;
const int inf=1e9+1;
const int mx=~0u>>1;
const int mod=1e9+7;
const int maxn=2e5+10;
using namespace std;
struct treap
{
    struct node
    {
        node *ch[2];
        int key,siz,wei,cnt;
        node(int _key,node * f)
        {
            ch[0]=ch[1]=f;
            key=_key;
            siz=cnt=1;
            wei=rand();
        }
        void push(){siz=ch[0]->siz+ch[1]->siz+cnt;}
    }*null,*root;
    treap()
    {
        null=new node(0,0);
        null->siz=null->cnt=0;null->wei=mx;
        root=null;
    }
    void rot(node *&rt,bool d)//把!d抬上来
    {
        node *c=rt->ch[!d];
        rt->ch[!d]=c->ch[d];
        c->ch[d]=rt;
        rt->push();c->push();
        rt=c;
    }
    void insert(const int &key,node *&rt)//插入
    {
        if(rt==null){rt=new node(key,null);return;}
        if(key==rt->key)
        {
            rt->cnt++;
            rt->siz++;return ;
        }
        bool d=key>rt->key;
        insert(key,rt->ch[d]);
        if(rt->wei>rt->ch[d]->wei)rot(rt,!d);
        rt->push();
    }
    void remove(const int &key,node *&rt)//删除
    {
        if(rt==null)return;
        bool d=key>rt->key;
        if(key==rt->key)
        {
            if(rt->cnt>1){rt->cnt--;rt->siz--;return ;}
             d=rt->ch[0]->wei>rt->ch[1]->wei;
             if(rt->ch[d]==null)
             {
                delete rt;
                rt=null;
                return ;
             }
             rot(rt,!d);
             remove(key,rt);
        }
        else remove(key,rt->ch[d]);
        rt->push();
    }
    void view(node *rt)
    {
        if(rt==null)
        {
            return ;
        }
        cout<<rt->key<<endl;
        view(rt->ch[0]);
        view(rt->ch[1]);
    }
    int rank(const int &key,node *rt)//查询key是第几大
    {
        if(rt==null)return 0;
        if(key==rt->key)return rt->ch[0]->siz+1;
        if(key<rt->key)return rank(key,rt->ch[0]);
        else return rt->ch[0]->siz+rt->cnt+rank(key,rt->ch[1]);
    }
    node *select(int k,node *rt)//查询第k大
    {
           // cout<<k<<endl;
            int s=rt->ch[0]->siz+rt->cnt;
            if(k>rt->ch[0]->siz&&k<=s)return rt;
             if(k>s)return select(k-s,rt->ch[1]);
            else return select(k,rt->ch[0]);
          //  if(k<s)return select(k-s,rt->ch[1]);
           // else return select(k,rt->ch[0]);
    }
    int pre(const int &k)//返回第一个比k小的树
    {
       node *t=root;
       int ret=0;
        while(t!=null)
        {
            if(t->key<k)ret=t->key,t=t->ch[1];
            else t=t->ch[0];
        }
        return ret;
    }
    int suc(const int &k)//返回第一个比k大的数
    {
         node *t=root;
       int ret=0;
        while(t!=null)
        {
            if(t->key>k)ret=t->key,t=t->ch[0];
            else t=t->ch[1];
        }
        return ret;
    }
};
int main()
{
    int n;
    treap ac=treap();
    scanf("%d",&n);
    while(n--)
    {
        int op,x;
        scanf("%d %d",&op,&x);
        if(op==1)ac.insert(x,ac.root);
        else if(op==2)ac.remove(x,ac.root);
        else if(op==3)printf("%d\n",ac.rank(x,ac.root));
        else if(op==4)printf("%d\n",ac.select(x,ac.root)->key);
        else if(op==5)printf("%d\n",ac.pre(x));
        else printf("%d\n",ac.suc(x));
      //  ac.view(ac.root);
    }
    return 0;
}

 

posted @ 2018-08-03 18:53  lhclqslove  阅读(123)  评论(0编辑  收藏  举报