奇妙的错误

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

Jacky2009 @ 2022-05-28 18:17:16

Treap代码如下

#include<bits/stdc++.h>
using namespace std;
int tot;
unsigned int seed=114514,root;
struct point{
    int l;
    int r,val,v,siz,cnt;
}a[100005];
int cr(int val){
    tot++;
    a[tot].val=val;
    a[tot].v=rand();
    a[tot].siz=a[tot].cnt=1;
    return tot;
}
void update(int n){
    a[n].siz=a[a[n].l].siz+a[a[n].r].siz+a[n].cnt;
}
int rank(int rk,int p){
    if(!p)return 0;

    if(rk<=(a[a[p].l].siz))return rank(rk,a[p].l);
    if(rk<=(a[a[p].l].siz)+a[p].cnt)return a[p].val;
    return rank(rk-a[a[p].l].siz-a[p].cnt,a[p].r);
}
int grank(int x,int p){
    if(!p)return 0;
    if(x==a[p].val)return a[a[p].l].siz+1;
    if(x<a[p].val){
        return grank(x,a[p].l);
    }
    return grank(x,a[p].r)+a[p].cnt+a[a[p].l].siz;
}
void zig(int &p){
    int q=a[p].l;
    a[p].l=a[q].r;
    a[q].r=p;
    update(a[p].r);
    update(p);
    p=q;
}
void zag(int &p){
    int q=a[p].r;
    a[p].r=a[q].l;
    a[q].l=p;
    update(a[p].l);
    update(p);
    p=q;
}
void Insert(int &p,int val){
    if(p==0){
        p=cr(val);
        return;
    }
    if(val==a[p].val){
        a[p].cnt++;
        update(p);
        return;
    }
    if(val<a[p].val){
        Insert(a[p].l,val);
        if(a[p].v<a[a[p].l].v)zig(p);

    }

    if(val>a[p].val){
        Insert(a[p].r,val);
        if(a[p].v<a[a[p].r].v)zag(p);

    }
    update(p);
}
void del(int p,int x){
    if(!p)return;
    if(x==a[p].val){
        if(a[p].cnt>1){
            a[p].cnt--;
            update(p);
            return;
        }
        if(a[p].l||a[p].r){
            if(a[p].r==0||a[a[p].l].v>a[a[p].r].v){
                zig(p);
                del(a[p].r,x);
            }

            else{
                zag(p);
                del(a[p].l,x);
            }
            update(p);
        }
        else p=0;
        return;
    }
    x<a[p].val?del(a[p].l,x):del(a[p].r,x);
    update(p);
}
int getpre(int p,int x){
    int ans=1;
    p=root;
    while(p){
        if(x==a[p].val){
            if(a[p].l>0){
                p=a[p].l;
                while(a[p].r>0)p=a[p].r;
                ans=p;
            }
            break;
        }
        if(a[p].val<x&&a[p].val>a[ans].val)ans=p;
        p=x<a[p].val?a[p].l:a[p].r;
    }
    return a[ans].val;
}
int getn(int p,int x){
    int ans=2;
 p=root;
    while(p){
        if(x==a[p].val){
            if(a[p].r>0){
                p=a[p].r;
                while(a[p].l>0)p=a[p].l;
                ans=p;
            }
            break;
        }
        if(a[p].val>x&&a[p].val<a[ans].val)ans=p;
        p=x<a[p].val?a[p].l:a[p].r;
    }
    return a[ans].val;
}
int main(){
    srand(seed);
    cr(-1145141919);
    cr(1145141919);
 root=1;
    a[1].r=2;
    update(root);
    int n,m,lastans=0,k;
    cin>>n>>m;
    int res=0;
    for(int i=1;i<=n;i++){
        cin>>k;
        Insert(root,k);//这里报错
    }
    for(int i=1;i<=m;i++){
        int op,x;
        cin>>op>>x;
        res^=lastans;
        x^=lastans;
        if(op==1){
            Insert(root,x);
        }
        else if(op==2){
            del(root,x);
        }
        else if(op==3){
            cout<<(lastans=grank(x,root))<<endl;
        }
        else if(op==4){
            cout<<(lastans=rank(x,root))<<endl;
        }
        else if(op==5){
            cout<<(lastans=getpre(root,x))<<endl;
        }
        else cout<<(lastans=getn(root,x))<<endl;
    }
    cout<<res<<endl;
}

请问为什么?


by Jacky2009 @ 2022-05-28 18:19:21

@bryce @yeszy @AFOier @Loser_King


|