[BST-SBT]POJ_3481_double queue

题意:裸的平衡树题

平衡树功能:插入,删除最大,删除最小

挂一个SBT模板吧,明天就校赛了,所以重写了一下SBT,把原来的删除操作改了下:

#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 1111111,INF = 10000001;
struct Key{
    int k,p;
    Key(){}
    Key(int kk,int pp):k(kk),p(pp){}
    bool operator < (const Key &ke) const{
        return p<ke.p;
    }
    bool operator >= (const Key &ke) const{
        return !(*this<ke);
    }
    bool operator == (const Key &ke) const{
        return p==ke.p;
    }
}k[MAXN];
int l[MAXN],r[MAXN],pool[MAXN],size[MAXN],T,top,node;
void build(){
    T = top = node = 0;
}
void left_rotate(int &x){
    int q = r[x];
    r[x] = l[q];
    l[q] = x;
    size[q] = size[x];
    size[x] = size[l[x]]+size[r[x]]+1;
    x = q;
}
void right_rotate(int &x){
    int q = l[x];
    l[x] = r[q];
    r[q] = x;
    size[q] = size[x];
    size[x] = size[l[x]]+size[r[x]]+1;
    x = q;
}
int newnode(Key key){
    int x;
    if(top!=0){
        x = pool[--top];
    }else{
        x = ++node;
    }
    k[x] = key;
    size[x] = 1; l[x] = r[x] = 0;
    return x;
}
void delnode(int x){
    pool[top++] = x;
    size[x] = l[x] = r[x] = 0;
}
void Maintain(int &T,bool flag){
    if(!flag){
        if(size[l[l[T]]]>size[r[T]]){
            right_rotate(T);
        }else if(size[r[l[T]]]>size[r[T]]){
            left_rotate(l[T]);
            right_rotate(T);
        }else{
            return;
        }
    }else{
        if(size[r[r[T]]]>size[l[T]]){
            left_rotate(T);
        }else if(size[l[r[T]]]>size[l[T]]){
            right_rotate(r[T]);
            left_rotate(T);
        }else{
            return;
        }
    }
    Maintain(l[T],0);
    Maintain(r[T],1);
    Maintain(T,0);
    Maintain(T,1);
}
void Insert(int &T,Key key){
    if(!T){
        T = newnode(key);
        return;
    }
    size[T]++;
    if(key<k[T])Insert(l[T],key);
    else Insert(r[T],key);
    Maintain(T,key>=k[T]);
}
Key Delete(int &T,Key key){
    if(!T)return Key(INF,INF);//no element to delete
    size[T]--;
    if((key==k[T])||(key<k[T]&&l[T]==0)||(key>=k[T]&&r[T]==0)){
        Key ret = k[T]; int x = T;
        if(l[T]==0||r[T]==0){
            T = l[T]+r[T];
            delnode(x);//释放结点内存
        }else{
            key.p++;
            k[T] = Delete(r[T],key);
        }
        return ret;
    }
    if(key<k[T])Delete(l[T],key);
    else Delete(r[T],key);
}
Key DeleteMax(int &T){
    if(!T)return Key(INF,INF);
    if(r[T])return DeleteMax(r[T]);
    int x = T; Key key = k[T];
    T = l[T];
    delnode(x);
    return key;
}
Key DeleteMin(int &T){
    if(!T)return Key(INF,INF);
    if(l[T])return DeleteMin(l[T]);
    int x = T; Key key = k[T];
    T = r[T];
    delnode(x);
    return key;
}
Key Select(int T,int st){
    if(!T)return Key(INF,INF);
    int rank = size[l[T]]+1;
    if(st==rank)return k[T];
    else if(st<rank)return Select(l[T],st);
    else return Select(r[T],st-rank);
}
int Rank(int T,Key key){
    if(!T)return -1;
    if(key==k[T])return size[l[T]]+1;
    else if(key<K[T])return Rank(l[T],key);
    else return size[l[T]]+1+Rank(r[T],key);
}
int main(){
    int op,rst,sec;
    build();
    //freopen("out.txt","w",stdout);
    while(scanf("%d",&op),op){
        if(op==1){
            scanf("%d%d",&rst,&sec);
            Insert(T,Key(rst,sec));
        }else if(op==2){
            Key key = Select(T,size[T]);
            if(key.k==INF)printf("0\n");
            else printf("%d\n",key.k);
            Delete(T,key);
        }else{
            Key key = Select(T,1);
            if(key.k==INF)printf("0\n");
            else printf("%d\n",key.k);
            Delete(T,key);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值