【Balanced Binary Tree】[NOI2004]郁闷的出纳员

题目
平衡树模板题,包含区间删除操作。

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000
int n,pre,bk,mi,ans,cg,size;
struct node{
    int val,pri,cnt,lsize,rsize;
    node *ls,*rs;
}treap_tree[MAXN+10],*tcnt=treap_tree,*root;
void Read(int &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}
void Rotate_left(node *&a){
    node *b=a->rs;
    a->rs=b->ls;
    b->ls=a;
    a->rsize=b->lsize;
    b->lsize=a->lsize+a->rsize+a->cnt;
    a=b;
}
void Rotate_right(node *&a){
    node *b=a->ls;
    a->ls=b->rs;
    b->rs=a;
    a->lsize=b->rsize;
    b->rsize=a->lsize+a->rsize+a->cnt;
    a=b;
}
void del(node *&p,int val){
    if(!p)
        return;
    if(val<=p->val){
        del(p->ls,val);
        if(p->ls)
            p->lsize=p->ls->lsize+p->ls->rsize+p->ls->cnt;
        else
            p->lsize=0;
    }
    else{
        ans+=p->cnt+p->lsize;
        p=p->rs;
        del(p,val);
    }
}
void Treap_insert(node *&p,int val){
    if(!p){
        p=++tcnt;
        p->cnt=1;
        p->val=val;
        p->pri=rand();
        return;
    }
    if(val>p->val){
        p->rsize++;
        Treap_insert(p->rs,val);
        if(p->rs->pri<p->pri)
            Rotate_left(p);
    }
    else if(val<p->val){
        p->lsize++;
        Treap_insert(p->ls,val);
        if(p->ls->pri<p->pri)
            Rotate_right(p);
    }
    else
        p->cnt++;
}
void pos_find(node *&p,int pos){
    if(pos<p->rsize)
        pos_find(p->rs,pos);
    else if(pos>=p->rsize+p->cnt)
        pos_find(p->ls,pos-p->rsize-p->cnt);
    else
        printf("%d\n",p->val+cg);
}
int main()
{
    char c[2];
    int i,a;
    srand(2015111913);
    Read(n),Read(mi);
    for(i=1;i<=n;i++){
        scanf("%s",c);
        Read(a);
        if(c[0]=='I'){
            if(a<mi)
                continue;
            size++;
            Treap_insert(root,a-cg);
        }
        else if(c[0]=='A')
            cg+=a;
        else if(c[0]=='S'){
            cg-=a;
            del(root,mi-cg);
        }
        else{
            if(a>size-ans)
                puts("-1");
            else
                pos_find(root,a-1);
        }
    }
    printf("%d\n",ans);
}

你可能感兴趣的:(数据结构,C++)