BZOJ 3224 Splay

来源:互联网 发布:网络上调查公司可靠吗 编辑:程序博客网 时间:2024/05/17 10:07

【题目分析】
显然是一道平衡树的裸题。然而我用treap完成之后又尝试用splay。无论是旋转还是插入删除,都已经做的很好了,但是size数组没有维护好。心好累,不想再改了,就这样吧。直接上代码,希望有人能找到我的错误


/**************************************************************    Problem: 3224    User: sdfzwxl    Language: C++    Result: Wrong_Answer****************************************************************/#include <cstdio>#include <iostream>#include <cstring>using namespace std;const int maxn=100010;int c[maxn][2],cnt,flag=0,v[maxn],f[maxn],w[maxn],size[maxn],n,t1,t2,rt,x,ans=0,b;inline int min(int a,int b){return a>b?b:a;}inline void up(int p){size[p]=size[c[p][0]]+size[c[p][1]]+w[p];}inline void rot(int x,int &k){    int y=f[x],z=f[y],l,r;    if (c[y][0]==x) l=0; else l=1; r=l^1;    if (y==k) k=x;    else{if (c[z][0]==y) c[z][0]=x;else c[z][1]=x;}    f[x]=z;f[y]=x;f[c[x][r]]=y;    c[y][l]=c[x][r];c[x][r]=y;    size[x]=size[y];    up(y);//    size[y]=size[c[y][0]]+size[c[y][1]]+w[y];}inline void splay(int x,int &k){    int y,z;    while (x!=k)    {        y=f[x];z=f[y];        if (y!=k)        {            if ((c[y][0]==x)^(c[z][0]==y)) rot(x,k);            else rot(y,k);        }        rot(x,k);    }}inline void ins(int &k,int x,int fa){    if (!k){k=++cnt;v[k]=x;f[k]=fa;size[k]=1;w[k]=1;splay(k,rt);return;}    size[k]++;    if (x==v[k]) w[k]++;    else if (x<v[k]) ins(c[k][0],x,k);    else if (x>v[k]) ins(c[k][1],x,k);    up(k);}inline void del(int &k,int x){    if (k==0) return ;    if (v[k]==x)     {        if (w[k]>1)        {            w[k]--;            size[k]--;            return ;        }        else{            if (c[k][0]*c[k][1]==0)            {                 f[c[k][0]+c[k][1]]=f[k];                 k=c[k][0]+c[k][1];            }            else if (size[c[k][0]]<size[c[k][1]]){                if (c[f[k]][1]==k)                rot(c[k][1],rt),del(c[k][1],x);                else rot(c[k][1],rt),del(c[k][0],x);            }            else if (c[f[k]][0]==k) rot(c[k][1],rt),del(c[k][0],x);              else rot(c[k][1],rt),del(c[k][1],x);        }        up(k);        return;    }    size[k]--;    if (v[k]<x) del(c[k][1],x);    else del(c[k][0],x);    up(k);}inline int qr(int k,int x){    if (!k) return 0;    if (x<v[k]) return qr(c[k][0],x);    if (x==v[k]) return size[c[k][0]]+1;    if (x>v[k]) return size[c[k][0]]+w[k]+qr(c[k][1],x);}inline int qn(int k,int x){    if (!k) return 0;    if (x<=size[c[k][0]]) return qn(c[k][0],x);    if (x>size[c[k][0]]+w[k]) return qn(c[k][1],x-size[c[k][0]]-w[k]);    else return v[k];}inline void qp(int k,int x){    if (!k) return;    if (v[k]<x){t1=v[k];qp(c[k][1],x);}    else qp(c[k][0],x);}inline void qs(int k,int x){    if (!k) return;    if (v[k]>x){t2=v[k];qs(c[k][0],x);}    else qs(c[k][1],x);}int main(){    scanf("%d",&n);    for (int i=1;i<=n;++i)    {        scanf("%d%d",&x,&b);        switch(x)        {            case 1:ins(rt,b,0); break;            case 2:del(rt,b); break;            case 3:printf("%d\n",qr(rt,b)); break;            case 4:printf("%d\n",qn(rt,b)); break;            case 5:qp(rt,b); printf("%d\n",t1);break;            case 6:qs(rt,b); printf("%d\n",t2);break;        }    }}
0 0