/*
poj3481 splay
Author:lcy
Time:2017-10-11
裸题
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
struct node{
    node *ch[2];//child
    int clt;
    int v;//value
    int s;//size
    int cnt;
    int cmp(int x){//该点与s比较,如果小于s返回0,即转向左子树
        if(ch[0]&&x<=ch[0]->s)
            return 0;
        if(ch[0]&&x<=ch[0]->s+cnt)
            return -1;
        if(!ch[0]&&x<=cnt)//没有左子树
            return -1;
        return 1;
    }
    void maintain(){
        s=cnt;
        if(ch[0]!=NULL)
            s+=ch[0]->s;
        if(ch[1]!=NULL)
            s+=ch[1]->s;
    }
    node(int x,int ct){
        ch[0]=ch[1]=NULL;
        cnt=s=1;
        v=x;
        clt=ct;
    }
};
struct splaytree{
    node *root;
    void rotate(node* &o,int d){//把根节点o的d儿子旋转上来
        if(o->ch[d]==NULL)return;
        node *s=o->ch[d];
        o->ch[d]=s->ch[d^1];s->ch[d^1]=NULL;
        s->ch[d^1]=o;
        o=s;
        o->ch[d^1]->maintain();
        o->maintain();
    }
    void splay(node* &o,int k){
        //printf("now=%d,rk=%d\n",o->v,k);
        int d=o->cmp(k);
        if(d==1){k-=o->cnt;if(o->ch[0])k-=o->ch[0]->s;}
        if(~d){
            int dd=o->ch[d]->cmp(k);
            if(~dd){
                int kk=k;
                if(dd==1){kk-=o->ch[d]->cnt;if(o->ch[d]->ch[0])kk-=o->ch[d]->ch[0]->s;}
                splay(o->ch[d]->ch[dd],kk);
                if(d==dd)//共线时先转上面的
                    rotate(o,d);
                else //折线时先转下面的
                    rotate(o->ch[d],dd);
            }
            rotate(o,d);//两种方法最后都要转上面的
        }
    }
    int _push(node* &o,int x,int rk,int ct){
        if(o==NULL){root=new node(x,ct);return 1;}//树为空
        int d;
        if(x>o->v){d=1;rk+=o->cnt;if(o->ch[0])rk+=o->ch[0]->s;}
        else if(x==o->v){rk+=o->cnt;o->cnt++;if(o->ch[0])rk+=o->ch[0]->s;o->maintain();return rk;}//相同元素不处理
        else d=0;
        if(o->ch[d]){
             int ans=_push(o->ch[d],x,rk,ct);
             o->maintain();
             return ans;
        }
        else{
            o->ch[d]=new node(x,ct);
            o->maintain();
            return rk;
        }
    }
    inline void push(int x,int ct){
        splay(root,_push(root,x,1,ct));
    }
    int _kth(node* &o,int k){
        int d=o->cmp(k);
        //printf("now=%d,k=%d\n",o->v,k);
        switch(d){
            case -1:
                return o->v;
            case 0:
                return _kth(o->ch[0],k);
            case 1:
                int kk=k-o->cnt;
                if(o->ch[0])kk-=o->ch[0]->s;
                return _kth(o->ch[1],kk);
        }
    }
    int kth(int x){
        return _kth(root,x);
    }
    int _idx(node *o,int x,int k){
        if(o->v==x){
            if(o->ch[0])k+=o->ch[0]->s;
            return k;
        }
        else if(x<o->v)
            return _idx(o->ch[0],x,k);
        else{
            if(o->ch[0])k+=o->ch[0]->s;
            k+=o->cnt;
            return _idx(o->ch[1],x,k);
        }
    }
    int idx(int x){
        return _idx(root,x,1);
    }
    void del(int k){//删除第k大元素
        splay(root,k);
        printf("%d\n",root->clt);
        node *t=root;
        if(root->ch[0]==NULL)root=root->ch[1];
        else if(root->ch[1]==NULL)root=root->ch[0];
        else{
            splay(root->ch[0],root->ch[0]->s);//把左子树最大值旋转到左子树根上
            root=root->ch[0];//此时左子树根节点没有右子树
            root->ch[1]=t->ch[1];
        }
        delete t;
    }
    void show(){
        printf("DFS---------------\n");
        dfs(root);
        printf("END---------------\n");
    }
    void dfs(node *o){
        printf("now=%d,size=%d\n",o->v,o->s);
        if(o->ch[0])
            printf("left son %d\n",o->ch[0]->v);
        if(o->ch[1])
            printf("right son %d\n",o->ch[1]->v);
        if(o->ch[0])dfs(o->ch[0]);
        if(o->ch[1])dfs(o->ch[1]);
    }
}spt;
int n,k,p;
int main(){
    while(~scfd(&n)&&n){
        if(n==1){
            scanf("%d%d",&k,&p);
            spt.push(p,k);
        }
        else if(n==2){
            if(spt.root==NULL){
                printf("0\n");
                continue;
            }
            spt.del(spt.root->s);
        }
        else if(n==3){
            if(spt.root==NULL){
                printf("0\n");
                continue;
            }
            spt.del(1);
        }
    }

    return 0;
}
 posted on 2017-10-11 20:31  cylcy  阅读(166)  评论(0)    收藏  举报