萌新求调 treap ,20pts 求助

P6136 【模板】普通平衡树(数据加强版)

Harry27182 @ 2021-11-14 09:47:08

rt,一直 20pts ,好像有输出负数和奇怪的数,求调

#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f
using namespace std;
int size[1100005],val[1100005],num[11000005],rd[1100005],son[1100005][2];
int n,cnt,root,op,x,m,last,ans;
void pushup(int p)
{
    size[p]=size[son[p][0]]+size[son[p][1]]+num[p];
} 
void rotate(int &p,int d)
{
    int k=son[p][d^1];
    son[p][d^1]=son[k][d];
    son[k][d]=p;
    pushup(p);
    pushup(k);
    p=k;
}
void insert(int &p,int x)
{
    if(!p)
    {
        p=++cnt;
        size[p]=num[p]=1;
        val[p]=x;
        rd[p]=rand();
        return;
    }
    if(val[p]==x)
    {
        num[p]++;
        size[p]++;
        return;
    }
    int d=(x>val[p]);
    insert(son[p][d],x);
    if(rd[p]<rd[son[p][d]])rotate(p,d^1);
    pushup(p);
}
void del(int &p,int x)
{
    if(!p)return;
    if(x<val[p])del(son[p][0],x);
    else if(x>val[p])del(son[p][1],x);
    else
    {
        if(!son[p][0]&&!son[p][1])
        {
            num[p]--;size[p]--;
            if(!num[p])p=0;
        }
        else if(!son[p][1])
        {
            rotate(p,1);
            del(son[p][1],x);
        }
        else if(!son[p][0])
        {
            rotate(p,0);
            del(son[p][0],x);
        }
        else
        {
            int d=(rd[son[p][0]]>rd[son[p][1]]);
            rotate(p,d);
            del(son[p][d],x);
        }
    }
    pushup(p);
}
int rnk(int p,int x)
{
    if(!p)return 1;
    if(val[p]==x)return size[son[p][0]]+1;
    if(val[p]<x)return size[son[p][0]]+num[p]+rnk(son[p][1],x);
    if(val[p]>x)return rnk(son[p][0],x);
}
int find(int p,int x)
{
    if(!p)return 0;
    if(size[son[p][0]]>=x)return find(son[p][0],x);
    else if(size[son[p][0]]+num[p]<x)return find(son[p][1],x-num[p]-size[son[p][0]]);
    else return val[p];
}
int pre(int p,int x)
{
    if(!p)return -inf;
    if(val[p]>=x)return pre(son[p][0],x);
    else return max(val[p],pre(son[p][1],x));
}
int suc(int p,int x)
{
    if(!p)return inf;
    if(val[p]<=x)return suc(son[p][1],x);
    else return min(val[p],suc(son[p][0],x));
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&x),insert(root,x);
    while(m--)
    {
        scanf("%lld%lld",&op,&x);
        x^=last;
        if(op==1)insert(root,x);
        else if(op==2)del(root,x);
        else if(op==3)last=rnk(root,x),ans^=last;
        else if(op==4)last=find(root,x),ans^=last;
        else if(op==5)last=pre(root,x),ans^=last;
        else last=suc(root,x),ans^=last;
    }
    printf("%lld",ans);
    return 0;
}

|