(bzoj 3224)

傳送門


Code

// by spli
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

int n;
struct node{
    int fa,c[2],siz,cnt,v;//cnt表示該節點代表多少個相同的值
}t[1000010];
int num;

void pushup(int p){//更新子樹中的節點數,類似線段樹
    t[p].siz=t[t[p].c[0]].siz+t[t[p].c[1]].siz+t[p].cnt;
}

void rot(int p,bool b){
    int f=t[p].fa;
    int y=t[p].c[b];
    int z=t[y].c[!b];
    t[f].c[t[f].c[0]!=p]=y;
    if(y) t[y].fa=f;
    t[y].c[!b]=p;
    if(p) t[p].fa=y;
    t[p].c[b]=z;
    if(z) t[z].fa=p;
    pushup(p);pushup(y);
}

void splay(int p){
    int f=t[p].fa;
    int ff=t[f].fa;
    if(!f) return;
    if(!ff){
        rot(f,t[f].c[0]!=p);
        return;
    }
    if((t[f].c[0]==p)^(t[ff].c[0]==f))
        rot(f,t[f].c[0]!=p),rot(ff,t[ff].c[0]!=p),splay(p);
    else rot(ff,t[ff].c[0]!=f),rot(f,t[f].c[0]!=p),splay(p);
}
void ins(int p,int v,int f,bool b){
    if(!p){
        p=++num;
        t[f].c[b]=p;
        t[p].fa=f;
        t[p].v=v;
        t[p].siz=t[p].cnt=1;
        splay(p);
        return;
    }
    t[p].siz++;
    if(t[p].v==v){
        t[p].cnt++;
        splay(p);
        return;
    }
    ins(t[p].c[v>t[p].v],v,p,v>t[p].v);
}

void del(int p,int v,int f,bool b){
    if(t[p].v==v){
        if(t[p].cnt>1){
            t[p].cnt--;t[p].siz--;
        }
        else if(t[p].c[0]==0&&t[p].c[1]==0)
            t[f].c[b]=0;
        else if(t[p].c[0]*t[p].c[1]==0){
            t[f].c[b]=t[p].c[0]+t[p].c[1];
            if(t[p].c[0]) t[t[p].c[0]].fa=f;
            else t[t[p].c[1]].fa=f;
        }
        else{
            rot(p,t[t[p].c[0]].siz>t[t[p].c[1]].siz);
            t[t[p].fa].siz--;
            del(p,v,t[p].fa,t[t[p].fa].c[0]!=p);
        }
        return;
    }
    t[p].siz--;
    del(t[p].c[v>t[p].v],v,p,v>t[p].v);
}

int getrank(int p,int v){
    if(!p) return 0;
    if(v<t[p].v) return getrank(t[p].c[0],v);
    if(v==t[p].v){
        int ans=t[t[p].c[0]].siz+1;
        splay(p);
        return ans;
    }
    return t[t[p].c[0]].siz+t[p].cnt+getrank(t[p].c[1],v);
}

int get_th(int p,int q){
    if(!p) return 0;
    if(q<=t[t[p].c[0]].siz) return get_th(t[p].c[0],q);
    if(q<=t[t[p].c[0]].siz+t[p].cnt){
        splay(p);
        return t[p].v;
    }
    return get_th(t[p].c[1],q-t[t[p].c[0]].siz-t[p].cnt);
}

int getpre(int p,int v){
    if(!p) return -1;
    if(t[p].v<v){
        int y=getpre(t[p].c[1],v);
        if(y==-1){
            splay(p);
            return t[p].v;
        }
        return y;
    }
    return getpre(t[p].c[0],v);
}

int getsuc(int p,int v){
    if(!p) return -1;
    if(t[p].v>v){
        int y=getsuc(t[p].c[0],v);
        if(y==-1){
            splay(p);
            return t[p].v;
        }
        return y;
    }
    return getsuc(t[p].c[1],v);
}

int main(){
    scanf("%d",&n);
    int op,x;
    while(n--){
        scanf("%d%d",&op,&x);
        if(op==1) ins(t[0].c[0],x,0,0);
        if(op==2) del(t[0].c[0],x,0,0);
        if(op==3) printf("%d\n",getrank(t[0].c[0],x));
        if(op==4) printf("%d\n",get_th(t[0].c[0],x));
        if(op==5) printf("%d\n",getpre(t[0].c[0],x));
        if(op==6) printf("%d\n",getsuc(t[0].c[0],x));
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章