3224: Tyvj 1728 普通平衡树(Splay裸题)

来源:互联网 发布:ise12.3软件下载 编辑:程序博客网 时间:2024/06/16 21:25

Link

http://www.lydsy.com/JudgeOnline/problem.php?id=3224

Problem

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Data constraint

n的数据范围:n<=100000

每个数的数据范围:[-2e9,2e9]

Solution

详见http://blog.csdn.net/algor_pro_king_john/article/details/78765142

#include <cstdio>#define N 1000000using namespace std;int cn,n,p,x,rt,sz,tr[N][2],fa[N],size[N],cnt[N],key[N];void update(int x){size[x]=cnt[x]+size[tr[x][0]]+size[tr[x][1]];}void clear(int x){size[x]=cnt[x]=key[x]=fa[x]=tr[x][0]=tr[x][1]=0;}int pre(){int nw=tr[rt][0]; while(nw && tr[nw][1])nw=tr[nw][1]; return (nw==0)?sz+1:nw;}int nex(){int nw=tr[rt][1]; while(nw && tr[nw][0])nw=tr[nw][0]; return (nw==0)?sz+1:nw;}int son(int x){return tr[fa[x]][1]==x;}void rotate(int x){if(x==0)return;    int y=fa[x], k=son(x);    if (fa[y]) tr[fa[y]][son(y)]=x;    if (tr[x][!k]) fa[tr[x][!k]]=y;    tr[y][k]=tr[x][!k],tr[x][!k]=y,fa[x]=fa[y],fa[y]=x,update(y),update(x);}void splay(int x){    for (int fat;fat=fa[x];rotate(x))        rotate(fa[fat]?((son(fat)==son(x))?fat:x):0); rt=x;}int fin(int x){    int nw=rt,rank=0;    while (1){        if (key[nw]>x)nw=tr[nw][0]; else        if (key[nw]==x){rank+=size[tr[nw][0]]+1, splay(nw); return rank;}else        rank+=size[tr[nw][0]]+cnt[nw], nw=tr[nw][1];    }}int fim(int x){    int nw=rt,rank=0;    while (1){        if (tr[nw][0] && rank+size[tr[nw][0]]>=x) nw=tr[nw][0]; else{            rank+=size[tr[nw][0]];            if (rank+cnt[nw]>=x) { splay(nw); return key[nw];}            rank+=cnt[nw], nw=tr[nw][1];        }    }}void ins(int x){    int nw=rt,fat;    while (1){        if (key[nw]==x) {cnt[nw]++,update(nw),splay(nw);break;}        fat=nw, nw=tr[nw][key[nw]<x];        if (nw==0){cnt[++sz]++,key[sz]=x,update(sz),fa[sz]=fat,tr[fat][key[fat]<x]=sz,splay(sz);break;}    }}void del(int x){    fin(x); int nw=rt,lefb;    if (cnt[rt]>1){cnt[rt]--,update(rt);return;}    if (!tr[rt][0]&&!tr[rt][1]){clear(rt),rt=0;return;}    if (!tr[rt][0]) {rt=tr[rt][1],fa[rt]=0,update(rt),clear(nw);return;}    if (!tr[rt][1]) {rt=tr[rt][0],fa[rt]=0,update(rt),clear(nw);return;}    lefb=pre(), splay(lefb), tr[rt][1]=tr[nw][1], fa[tr[nw][1]]=rt, update(rt), clear(nw);}int main(){    key[0]=2e9+1;    for(scanf("%d",&n);n;n--){        scanf("%d%d",&p,&x);        switch(p){            case 1:ins(x); break;            case 2:del(x); break;            case 3:printf("%d\n",fin(x)); break;            case 4:printf("%d\n",fim(x)); break;            case 5:ins(x), printf("%d\n",key[pre()]), del(x); break;            case 6:ins(x), printf("%d\n",key[nex()]), del(x); break;        }    }}
原创粉丝点击