treap模板

19 篇文章 0 订阅
13 篇文章 0 订阅

[Tyvj 1728]普通平衡树
★★ 输入文件:phs.in 输出文件:phs.out 简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
【输入格式】

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
【输出格式】

对于操作3,4,5,6每行输出一个数,表示对应答案
【样例输入】

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
【样例输出】

106465
84185
492737
【提示】

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
using namespace std;
struct node{
    node *left,*right;
    int v,p,cnt,sz;
}*root,*null=new node((node){null,null,0,0,0,0});
int in(){
    int x=0; char ch=getchar(); bool f=true;
    while (ch<'0' || ch>'9'){
        if (ch=='-') f=false;
        ch=getchar();
    }
    while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    if (!f) x=-x;
    return x;
}
void push_up(node *x){
    x->sz=x->left->sz+x->right->sz+x->cnt;
}
void lturn(node *&x){
    node *y=x->right;
    x->right=y->left; y->left=x;
    y->sz=x->sz; push_up(x); x=y;
}
void rturn(node *&x){
    node *y=x->left;
    x->left=y->right; y->right=x;
    y->sz=x->sz; push_up(x); x=y;
}
void Insert(node *&x,int k){
    if (!x->sz){
        x=new node;
        x->left=x->right=null;
        x->v=k; x->p=rand();
        x->sz=x->cnt=1;
        return;
    }
    x->sz++;
    if (k==x->v) x->cnt++;
    else if (k>x->v){
        Insert(x->right,k);
        if (x->right->p<x->p) lturn(x);
    }
    else {
        Insert(x->left,k);
        if (x->left->p<x->p) rturn(x);
    }
}
void Delete(node *&x,int k){
    if (!x->sz) return;
    if (k==x->v){
        if (x->cnt>1) x->cnt--,x->sz--;
        else if (!x->left->sz || !x->right->sz){
            node *t=x;
            if (!x->left->sz) x=x->right;
            else x=x->left;
            delete t;
        }
        else if (x->left->p<x->right->p)
            rturn(x),Delete(x,k);
        else lturn(x),Delete(x,k);
    }
    else if (k<x->v) x->sz--,Delete(x->left,k);
    else x->sz--,Delete(x->right,k);
}
int Q_rank(node *x,int k){
    if (!x->sz) return 0;
    if (k==x->v) return x->left->sz+1;
    else if (k<x->v) return Q_rank(x->left,k);
    else return Q_rank(x->right,k)+x->left->sz+x->cnt;
}
int Q_num(node *x,int k){
    if (!x->sz) return 0;
    if (k<=x->left->sz) return Q_num(x->left,k);
    else if (k>x->left->sz+x->cnt)
        return Q_num(x->right,k-x->left->sz-x->cnt);
    else return x->v;
}
int Q_pro(node *x,int k,int c){
    if (!x->sz) return c;
    if (k>x->v) return Q_pro(x->right,k,x->v);
    else return Q_pro(x->left,k,c);
}
int Q_suc(node *x,int k,int c){
    if (!x->sz) return c;
    if (k<x->v) return Q_suc(x->left,k,x->v);
    else return Q_suc(x->right,k,c);
}
int main(){
    freopen("phs.in","r",stdin);
    freopen("phs.out","w",stdout);
    int n=in(); root=null; srand(time(0));
    while (n--){
        int opt=in(),x=in();
        switch (opt){
            case 1:Insert(root,x); break;
            case 2:Delete(root,x); break;
            case 3:printf("%d\n",Q_rank(root,x)); break;
            case 4:printf("%d\n",Q_num(root,x)); break;
            case 5:printf("%d\n",Q_pro(root,x,0)); break;
            case 6:printf("%d\n",Q_suc(root,x,0)); break;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值