平衡树

#include<cstdio>
#include<cstring>
#include<ctime>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define clr(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define mkp(a,b) make_pair(a,b)
int read(){
    int ans=0,f=1;
    char c=getchar();
    while(!isdigit(c)){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(isdigit(c)){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return ans*f;
}
const int maxn=500009,inf=0x3fffffff;
struct node{
    int s,v,r;
    node*ch[2];
    inline void maintain(){
        s=ch[0]->s+ch[1]->s+1;
    }
}pool[maxn<<2],*root,*pt=pool,*null;
int n;
node*newnode(int x){
    pt->s=1;pt->ch[0]=pt->ch[1]=null;
    pt->r=rand()*rand();
    pt->v=x;
    return pt++;
}
void rot(node*&o,int d){
    node*t=o->ch[d^1];
    o->ch[d^1]=t->ch[d];t->ch[d]=o;
    o->maintain();t->maintain();
    o=t;
}
void insert(node*&o,int x){
    if(o==null) o=newnode(x);
    else{
        if(x<o->v){
            insert(o->ch[0],x);
            if(o->ch[0]->r>o->r) rot(o,1);
        }else{
            insert(o->ch[1],x);
            if(o->ch[1]->r>o->r) rot(o,0);
        }
    }
    o->maintain();
}
void del(node*&o,int x){
    if(o->v==x){
        if(o->ch[0]!=null&&o->ch[1]!=null){
            if(o->ch[0]->r>o->ch[1]->r){
                rot(o,1);del(o->ch[1],x);
            }else{
                rot(o,0);del(o->ch[0],x);
            }
        }else if(o->ch[0]!=null) o=o->ch[0];
        else o=o->ch[1];
    }else{
        if(x<o->v) del(o->ch[0],x);
        else del(o->ch[1],x);
    }
    if(o!=null) o->maintain();
} 
int rank(node*o,int x){
    if(o==null) return inf;
    if(x==o->v)    return min(rank(o->ch[0],x),o->ch[0]->s+1);
    if(x<o->v) return rank(o->ch[0],x);
    return rank(o->ch[1],x)+o->ch[0]->s+1;
}
int num(node*o,int x){
    if(x==o->ch[0]->s+1) return o->v;
    if(x<=o->ch[0]->s) return num(o->ch[0],x);
    return num(o->ch[1],x-o->ch[0]->s-1);
}
int pre(node*o,int x){
    if(o==null) return -1;
    return x<=o->v?pre(o->ch[0],x):max(o->v,pre(o->ch[1],x));
}
int suc(node*o,int x){
    if(o==null) return inf;
    return x>=o->v?suc(o->ch[1],x):min(o->v,suc(o->ch[0],x));
}
void init(){
    null=newnode(0);
    null->s=null->r=0;
    root=null;
}
int main(){
    init();
    n=read();
    rep(i,1,n){
        int opt=read(),x=read();
        if(opt==1) insert(root,x);
        else if(opt==2) del(root,x);
        else if(opt==3) printf("%d\n",rank(root,x));
        else if(opt==4) printf("%d\n",num(root,x));
        else if(opt==5) printf("%d\n",pre(root,x));
        else printf("%d\n",suc(root,x));
    }
    return 0;
}
treap

 是不是应该学一学sbt?

posted @ 2017-10-30 21:15  ChenThree  阅读(148)  评论(0编辑  收藏  举报