FHQ-Treap的奇妙WA 悬赏

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

Benzenesir @ 2022-08-30 12:16:41

是这样的,我自己测试样例,发现有时候能输出正确,有时候答案是错的,有时候在 5 8 这里就不动了,求dalao赐教

#include <iostream>
#include <queue>
#include <time.h>
#include <string.h>

using namespace std;
const int maxN=2*1e6+10;
int n,m; int r1=0,r2=0,r3=0;
int son[maxN][2],fa[maxN],size[maxN],val[maxN],data[maxN],root,idx;
int rd[maxN];
queue<int> rb;

inline void update(int x){
    if(x==0) return ;
    size[x]=size[son[x][1]]+size[son[x][0]]+1;
    //cout << x << endl;
    //cout << size[son[x][1]] << " " << size[son[x][0]] << endl;
}

inline void split(int now,int k,int &x,int &y){//按权值分裂,小于等于k的分到左子树,大于的分到右子树 
    if(!now){
        x=y=0; 
    }
    else{
        if(data[now]<=k){
            x=now;
            split(son[now][1],k,son[now][1],y);//这里我们已经把x更新为now了,由于treap的结构坚不可摧,所以右子树都是大于now的,所以再合并时就把其合并到now的右儿子上 
        }
        else{
            y=now;
            split(son[now][0],k,x,son[now][0]);
        }
    }
    update(now);
}

inline int merge(int a,int b){
    if(!a||!b) return a+b;
    if(val[a]<val[b]){
        son[a][1]=merge(son[a][1],b);//将右子树和b合并,作为a的新右子树 
        update(a);
        return a;
    }
    else{
        son[b][0]=merge(a,son[b][0]);//同理 
        update(b);
        return b;
    }
}

inline int new_point(int v){
    int p;
    if(!rb.empty()) {
        p=rb.front();
        rb.pop();
    }
    else p=++idx;
    size[p]=1;
    val[p]=rand();
    while(rd[val[p]]) val[p]=rand();
    rd[val[p]]=1;
    data[p]=v;
    //cout << size[p] << " " << val[p] << " " << data[p] << endl;
    return p;
}

inline void insert(int x){
    int r1,r2;
    split(root,x,r1,r2);
    root=merge(merge(r1,new_point(x)),r2);
}

inline void del(int x){//就算x不在bst里面,我们也能通过split找到它 
    int r1,r2,r3;
    split(root,x,r1,r2);
    split(r1,x-1,r1,r3);
    rb.push(r3); 
    r3=merge(son[r3][0],son[r3][1]);
    root=merge(merge(r1,r3),r2);
}

inline int inrank(int x){
    int r1,r2;
    int ans;
    split(root,x-1,r1,r2);
    ans=size[r1]+1;
    root=merge(r1,r2);
    return ans;
}

inline int kth(int k){
    int now=root;
    while(1){
        if(size[son[now][0]]<k&&size[son[now][0]]+1>=k){
            return data[now];
        }
        if(size[son[now][0]]>=k){
            now=son[now][0];
        }
        else{
            k-=size[son[now][0]]+1,now=son[now][1];
        }
    }
}

inline int pre(int x){
    return kth(inrank(x)-1);
}
inline int suffix(int x){
    return kth(inrank(x+1));//这里我们将值加一,其排名一定是最小的严格大于x的数的排名 
}

signed main(){
    //freopen("P6136_1.in","r",stdin);
    //freopen("FHQ.out","w",stdout);
    //memset(size,0,sizeof(size));
    srand(time(0));
    ios::sync_with_stdio(false);//cin加速 
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);//再度加速 
    //不能用printf,scanf
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        int x;cin >> x;
        insert(x);
    //  cout << size[root] << endl;
    }
    int last=0,ans;
    //del(4);
    //insert(9);
    //cout << inrank(10) << endl;

    while(m--){
        //cout << data[root] << endl;
        int opt,x;
        cin >> opt >> x;
        x^=last;
        //cout << x << endl;
        switch (opt){
            case 1:
                insert(x);
                break;
            case 2:
                del(x);
                break;
            case 3:
                last=inrank(x);
            //  cout << last << endl;
                ans^=last;
                break;
            case 4:
                last=kth(x);
            //  cout << last << endl;
                ans^=last;
                break;      
            case 5:
                last=pre(x);
                //cout << inrank(x) << endl;
                //cout << last << endl;
                ans^=last;
                break;
            case 6:
                last=suffix(x);
            //  cout << last << endl;
                ans^=last;
                break;  
        }
    }
    cout << ans << endl;

    return 114514-114514;
}
/*
treap中,由于随机值的存在,所以bst中的每一个节点只代表一个数,相同的数会被分配到不同的节点中,不像splay需要维护cnt 
*/

by Benzenesir @ 2022-09-03 00:07:36

Rebuild已A,磁铁完结


|