bzoj3224: Tyvj 1728 普通平衡树

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

题意:中文题。

分析:treap模板练习。其实知道了怎么旋转就知道了整个treap啦,实现的时候注意细节即可。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=15;
const int M=1e5+7;
const int HASHSIZE=3e5+9;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=~0u>>1;
const ll MAX=1ll<<55;
const double pi=acos(-1.0);
typedef double db;
typedef unsigned long long ull;
struct Treap {
    struct node {
        node *son[2];
        int key,siz,wei,cnt;
        node(int _key,node *f) {
            son[0]=son[1]=f;
            key=_key;siz=cnt=1;wei=rand();
        }
        void pushup() {
            siz=son[0]->siz+son[1]->siz+cnt;
        }
    }*null,*root;
    Treap() {
        null=new node(0,0);
        null->siz=null->siz=0;
        null->wei=INF;root=null;
    }
    void rot(node* &rt,bool d) {
        node* c=rt->son[!d];rt->son[!d]=c->son[d];
        c->son[d]=rt;rt->pushup();c->pushup();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->son[d]);
        if (rt->wei>rt->son[d]->wei) rot(rt,!d);
        rt->pushup();
    }
    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->son[0]->wei>rt->son[1]->wei;
            if (rt->son[d]==null) {
                delete rt;rt=null;return ;
            }
            rot(rt,!d);remove(key,rt->son[!d]);
        } else remove(key,rt->son[d]);
        rt->pushup();
    }
    node* select(int k,node* rt) {
        int s=rt->son[0]->siz+rt->cnt;
        if (k>=rt->son[0]->siz+1&&k<=s) return rt;
        if (s>k) return select(k,rt->son[0]);
        else return select(k-s,rt->son[1]);
    }
    int rank(const int &key,node* rt) {
        if (rt==null) return 0;
        int s=rt->son[0]->siz+rt->cnt;
        if (key==rt->key) return rt->son[0]->siz+1;
        if (key<rt->key) return rank(key,rt->son[0]);
        else return s+rank(key,rt->son[1]);
    }
    int pre(const int &k) {
        node* t=root;int ret=0;
        while (t!=null)
        if (t->key<k) ret=t->key,t=t->son[1];
        else t=t->son[0];
        return ret;
    }
    int sub(const int &k) {
        node* t=root;int ret=0;
        while (t!=null)
        if (t->key>k) ret=t->key,t=t->son[0];
        else t=t->son[1];
        return ret;
    }
};
int main()
{
    int i,a,b,n;
    Treap tree;
    scanf("%d", &n);
    while (n--) {
        scanf("%d%d", &a, &b);
        if (a==1) tree.insert(b,tree.root);
        if (a==2) tree.remove(b,tree.root);
        if (a==3) printf("%d\n", tree.rank(b,tree.root));
        if (a==4) printf("%d\n", tree.select(b,tree.root)->key);
        if (a==5) printf("%d\n", tree.pre(b));
        if (a==6) printf("%d\n", tree.sub(b));
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值