BZOJ 3224: Tyvj 1728 普通平衡树

题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3224


题目大意:维护平衡树的6个操作。


算法讨论:

        平衡树裸题。

        具体就不多说了,我用的是Treap。


Code:

/*
 * Problem:3224
 * Author:PYC
 */
 
#include <cstdio>
#include <cstdlib>
#include <algorithm>
 
#define maxn 1000000
#define oo 1000000000
 
using namespace std;
 
int m,tot,root;
 
struct node{int key,val,aux,l,r,ll,rr;}tree[maxn];
 
inline void zig(int &root){
    int t=tree[root].l;
    tree[root].l=tree[t].r;
    tree[root].ll=tree[t].rr;
    tree[t].r=root;
    tree[t].rr=tree[t].rr+tree[root].rr+tree[root].val;
    root=t;
}
 
inline void zag(int &root){
    int t=tree[root].r;
    tree[root].r=tree[t].l;
    tree[root].rr=tree[t].ll;
    tree[t].l=root;
    tree[t].ll=tree[t].ll+tree[root].ll+tree[root].val;
    root=t;
}
 
void insert(int &root,int y){
    if (!root){
        root=++tot;
        tree[root].key=y;
        tree[root].val=1;
        tree[root].aux=rand();
        return;
    }
    if (y==tree[root].key){tree[root].val++;return;}
    if (y<tree[root].key){
        insert(tree[root].l,y);
        tree[root].ll++;
        if (tree[root].aux>tree[tree[root].l].aux) zig(root);
        return;
    }
    if (y>tree[root].key){
        insert(tree[root].r,y);
        tree[root].rr++;
        if (tree[root].aux>tree[tree[root].r].aux) zag(root);
        return;
    }
}
 
void del(int &root,int y){
    if (!root) return;
    if (y==tree[root].key){
        if (tree[root].val>1){tree[root].val--;return;}
        if (!tree[root].l || !tree[root].r){
            if (!tree[root].l){root=tree[root].r;return;}
            if (!tree[root].r){root=tree[root].l;return;}
        }
        if (tree[tree[root].l].aux<tree[tree[root].r].aux){
            zig(root);
            del(tree[root].r,y);
            tree[root].rr--;
            return;
        }
        else{
            zag(root);
            del(tree[root].l,y);
            tree[root].ll--;
            return;
        }
    }
    if (y<tree[root].key){
        del(tree[root].l,y);
        tree[root].ll--;
        return;
    }
    if (y>tree[root].key){
        del(tree[root].r,y);
        tree[root].rr--;
        return;
    }
}
 
int rank(int &root,int y){
    if (!root) return 0;
    if (y==tree[root].key) return tree[root].ll+1;
    if (y<tree[root].key) return rank(tree[root].l,y);
    if (y>tree[root].key) return tree[root].ll+tree[root].val+rank(tree[root].r,y);
}
 
int kth(int &root,int y){
    if (!root) return 0;
    if (y<=tree[root].ll) return kth(tree[root].l,y);
    if (y>tree[root].ll && y<=tree[root].ll+tree[root].val) return tree[root].key;
    if (y>tree[root].ll+tree[root].val) return kth(tree[root].r,y-tree[root].ll-tree[root].val);
}
 
int pred(int &root,int y){
    if (!root) return -oo;
    if (y<=tree[root].key) return pred(tree[root].l,y);
    if (y>tree[root].key) return max(tree[root].key,pred(tree[root].r,y));
}
 
int succ(int &root,int y){
    if (!root) return oo;
    if (y>=tree[root].key) return succ(tree[root].r,y);
    if (y<tree[root].key) return min(tree[root].key,succ(tree[root].l,y));
}
 
int main(){
    srand(0);
    scanf("%d",&m);
    for (int i=1;i<=m;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        switch (x){
            case 1:insert(root,y);break;
            case 2:del(root,y);break;
            case 3:printf("%d\n",rank(root,y));break;
            case 4:printf("%d\n",kth(root,y));break;
            case 5:printf("%d\n",pred(root,y));break;
            case 6:printf("%d\n",succ(root,y));break;
        }
    }
    return 0;
}

By Charlie Pan

Mar 6,2014

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值