bzoj 3224(非旋转treap)

来源:互联网 发布:电路热仿真软件 编辑:程序博客网 时间:2024/05/17 12:24

传送门
附上两篇讲解:
http://www.cnblogs.com/nietzsche-oier/p/6748292.html
http://blog.csdn.net/zmh964685331/article/details/50536410
P.S.非旋转treap比普通treap慢,比splay快,可以实现splay能实现的而其余平衡树无法实现的操作比如区间翻转。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define mp(x,y) make_pair(x,y)const int MAXN=1e5+4;typedef pair<int ,int > pii;struct Node {    int lc,rc,val,key,siz;}t[MAXN];int n,x,root,cnt,opt;inline void update(int rt) {    t[rt].siz=t[t[rt].lc].siz+t[t[rt].rc].siz+1;}pii split(int a,int n) {    if (!n) return mp(0,a);    int lc(t[a].lc),rc(t[a].rc);    if (n==t[lc].siz) return t[a].lc=0,update(a),mp(lc,a);    if (n==t[lc].siz+1) return t[a].rc=0,update(a),mp(a,rc);    if (n<t[lc].siz) {        pii tmp=split(lc,n);        t[a].lc=tmp.second,update(a);        return mp(tmp.first,a);    }    pii tmp=split(rc,n-t[lc].siz-1);    t[a].rc=tmp.first,update(a);    return mp(a,tmp.second);}int merge(int a,int b) {    if (!a||!b) return a+b;    if (t[a].key<t[b].key) return t[a].rc=merge(t[a].rc,b),update(a),a;    else return t[b].lc=merge(a,t[b].lc),update(b),b;}int rank(int x,int rt) {//x的排名    int ret=0,tmp=1e9;    while (rt) {        if (x==t[rt].val) tmp=min(tmp,ret+t[t[rt].lc].siz+1);        if (x>t[rt].val) ret+=t[t[rt].lc].siz+1,rt=t[rt].rc;        else rt=t[rt].lc;    }    return tmp==(int)1e9?ret:tmp;}int find(int x,int rt) {    while (true) {        if (t[t[rt].lc].siz==x-1) return t[rt].val;        if (t[t[rt].lc].siz>x-1) rt=t[rt].lc;        else x-=t[t[rt].lc].siz+1,rt=t[rt].rc;    }}int pre(int x,int rt) {    int ret=-1e9;    while (rt) {        if (x>t[rt].val) ret=max(ret,t[rt].val),rt=t[rt].rc;        else rt=t[rt].lc;    }    return ret;}int nxt(int x,int rt) {    int ret=1e9;    while (rt) {        if (x<t[rt].val) ret=min(ret,t[rt].val),rt=t[rt].lc;        else rt=t[rt].rc;    }    return ret;}inline void Insert(int x) {    int k=rank(x,root);    pii tmp=split(root,k);    t[++cnt].val=x;    t[cnt].key=rand();    t[cnt].siz=1;    root=merge(tmp.first,cnt);    root=merge(root,tmp.second);}inline void del(int x){    int k=rank(x,root);    pii t1=split(root,k);    pii t2=split(t1.first,k-1);    root=merge(t2.first,t1.second);}int main() {//  freopen("bzoj 3224.in","r",stdin);    scanf("%d",&n);    for (register int i=0;i<n;++i) {        scanf("%d%d",&opt,&x);        switch (opt) {            case 1:Insert(x);break;            case 2:del(x);break;            case 3:printf("%d\n",rank(x,root));break;            case 4:printf("%d\n",find(x,root));break;            case 5:printf("%d\n",pre(x,root));break;            case 6:printf("%d\n",nxt(x,root));break;        }    }    return 0;}
原创粉丝点击