萌新求助!求助dalao帮助查错(treap)

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

USSENTERPRISE @ 2020-05-22 23:32:43

rt

对于样例好像在操作3 13(解密后3 8)那里有点问题,但是对比多份代码一直没有找到错误

求助!

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<algorithm>

using namespace std;

#define ll long long
#define ull unsigned long long
#define rg register

namespace Enterprise{

    inline int read(){
        int s=0,f=0;
        int ch=getchar();
        while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
        while(isdigit(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
        return f?-s:s;
    }

    const int N=1e5+15;
    int ch[N][2],dat[N],val[N],cnt[N],size[N],tot,n,m;
    int root;

    const int inf=(1<<30)+5;

   inline int add(int v){
        dat[++tot]=rand();
        val[tot]=v;
        cnt[tot]=1;
        size[tot]=1;
        return tot;
    }

    inline void pushup(int id){
        size[id]=size[ch[id][0]]+size[ch[id][1]]+cnt[id];
    }

    inline void build(){
        root=add(-inf);
        ch[root][1]=add(inf);
        pushup(root);
    }

    inline void rotate(int &id,int d){
        rg int tmp=ch[id][d^1];
        ch[id][d^1]=ch[tmp][d];
        ch[tmp][d]=id;
        id=tmp;
        pushup(ch[id][d]),pushup(id);
    }

    inline void insert(int &id,int v){
        if(!id){
            id=add(v);
            return;
        }
        if(v==val[id]){cnt[id]++;pushup(id);return;}
        rg int d=v<val[id]?0:1;
        insert(ch[id][d],v);
        if(dat[id]>dat[ch[id][d]]) rotate(id,d^1);
        pushup(id);
    }

    inline void remove(int &id,int v){
        if(!id) return;
        if(v==val[id]){
            if(cnt[id]>1){ cnt[id]--;pushup(id); return; }
            if(ch[id][0]||ch[id][1]){
                if(!ch[id][1] || dat[ch[id][0]] > dat[ch[id][1]]){
                    rotate(id,1),remove(ch[id][1],v);
                }
                else rotate(id,0),remove(ch[id][0],v);
                pushup(id);
            }
            else id=0;
            return;
        }
        v<val[id]? remove(ch[id][0],v):remove(ch[id][1],v);
        pushup(id);
    }

    inline int get_rank(int id,int v){
        if(! id) return 0;
        if(v==val[id]) return size[ch[id][0]]+1;
        else if(v<val[id]) return get_rank(ch[id][0],v);
        else return size[ch[id][0]]+cnt[id]+get_rank(ch[id][1],v);
    }

    inline int get_val(int id,int rk){
        if(!id) return inf;
        if(rk <= size[ch[id][0]]) return get_val(ch[id][0],rk);
        else if(rk <= size[ch[id][0]]+cnt[id] ) return val[id];
        else return get_val(ch[id][1],rk-size[ch[id][0]]-cnt[id]);
    }

    inline int get_pre(int v){
        int id=root,pre;
        while(id){
            if(val[id]<v) pre=val[id],id=ch[id][1];
            else id=ch[id][0];
        }
        return pre;
    }

    inline int get_nxt(int v){
        int id=root,nxt;
        while(id){
            if(val[id]>v) nxt=val[id],id=ch[id][0];
            else id=ch[id][1];
        }
        return nxt;
    }

    int ans=0;

    inline void IEE(){
        n=read(),m=read();
        for(rg int i=1;i<=n;i++){
            int v=read();
            insert(root,v);
        }
        int last=0;
        for(rg int i=1;i<=m;i++){
            int opt=read(),v=read();
            v^=last;
            // printf("%d ",v);
            switch(opt){
                case 1: insert(root,v);break;
                case 2: remove(root,v);break;
                case 3: last=get_rank(root,v)-1;ans^=last;break;
                case 4: last=get_val(root,v+1);ans^=last;break;
                case 5: last=get_pre(v);ans^=last;break;
                case 6: last=get_nxt(v);ans^=last;break;
            }
            // printf("%d\n",last);
        }
        printf("%d",ans);
    }
}

signed main(){
    Enterprise::IEE();
    //system("pause");
    return 0;
}

|