关于fhq_treap按排名分裂的疑问
查看原帖
关于fhq_treap按排名分裂的疑问
694969
hcy1117楼主2025/7/19 17:12

每次插入都新增一个点可以AC,但如果对于相同的值存在一个点,记录cnt就只有72分,是哪里有问题?

//每次直接插入
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int x = 0,f = 1;char ch;
    do {ch = getchar();if(ch == '-') f = -1;} while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch-48,ch = getchar();
    return x * f;
}
inline void write(int x){
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + 48);
}
const int N = 100005;
int n,m;
int a[N];
struct Treap{
    int tot;
    int root,ls[N * 11],rs[N * 11];
    struct node{
        int val,pri,siz;
    }tr[N * 11];
    inline void newnode(int val){
        tr[++tot] = {val,rand(),1};
    }
    inline void pushup(int p){
        tr[p].siz = tr[ls[p]].siz + tr[rs[p]].siz + 1;
    }
    inline void split(int p,int rk,int &rt1,int &rt2){
        if(!p) {rt1 = rt2 = 0;return ;}
        if(tr[ls[p]].siz >= rk) rt2 = p,split(ls[p],rk,rt1,ls[p]);
        else rt1 = p,split(rs[p],rk - tr[ls[p]].siz - 1,rs[p],rt2);
        pushup(p);
    }
    inline int merge(int p,int q){
        if(!p || !q) return p ^ q;
        if(tr[p].pri < tr[q].pri){
            rs[p] = merge(rs[p],q),pushup(p);
            return p;
        }
        else {
            ls[q] = merge(p,ls[q]),pushup(q);
            return q;
        }
    }
    inline int query(int p,int val){
        if(!p) return 0;
        if(val < tr[p].val) return query(ls[p],val);
        else if(val == tr[p].val) return tr[ls[p]].siz;
        else return tr[ls[p]].siz + 1 + query(rs[p],val);
    }
    inline int query_rank(int val){
        return query(root,val) + 1;
    }
    inline void insert(int val){
        int rk = query_rank(val);
        int rt1;
        split(root,rk-1,rt1,root);
        newnode(val),root = merge(merge(rt1,tot),root);
    }
    inline void erase(int val){
        int rk = query_rank(val);
        int rt1 = 0,rt2;
        split(root,rk-1,rt1,root),split(root,1,root,rt2);
        root = merge(rt1,rt2);
    }
    inline int query_val(int rk){
        if(rk < 1 || rk > tr[root].siz) return 0;
        int rt1 = 0,rt2 = 0,ans;
        split(root,rk-1,rt1,root),split(root,1,root,rt2);
        ans = tr[root].val;
        root = merge(merge(rt1,root),rt2);
        return ans;
    }
    inline int query_pre(int val){
        return query_val(query_rank(val) - 1);
    }
    inline int query_suf(int val){
        return query_val(query_rank(val + 1));
    } 
}T;
signed main(){
    n = read(),m = read();
    srand(time(0));
    for(int i = 1;i <= n;i++) a[i] = read(),T.insert(a[i]);
    int lst = 0,ans = 0;
    while(m--){
        int opt = read(),x = read() ^ lst;
        if(opt == 1) T.insert(x);
        else if(opt == 2) T.erase(x);
        else if(opt == 3) lst = T.query_rank(x),ans ^= lst;
        else if(opt == 4) lst = T.query_val(x),ans ^= lst;
        else if(opt == 5) lst = T.query_pre(x),ans ^= lst;
        else lst = T.query_suf(x),ans ^= lst;
    }
    write(ans);
    return 0;
}
//记录cnt的
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int x = 0,f = 1;char ch;
    do {ch = getchar();if(ch == '-') f = -1;} while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch-48,ch = getchar();
    return x * f;
}
inline void write(int x){
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + 48);
}
const int N = 100005;
int n,m;
int a[N];
struct Treap{
    int tot;
    int root,ls[N * 11],rs[N * 11];
    struct node{
        int val,pri,cnt,siz;
    }tr[N * 11];
    inline void newnode(int val){
        tr[++tot] = {val,rand(),1,1};
    }
    inline void pushup(int p){
        tr[p].siz = tr[ls[p]].siz + tr[rs[p]].siz + tr[p].cnt;
    }
    inline void split(int p,int rk,int &rt1,int &rt2,int &rt3){
        if(!p) {rt1 = rt2 = rt3 = 0;return ;}
        if(tr[ls[p]].siz >= rk) rt3 = p,split(ls[p],rk,rt1,rt2,ls[p]);
        else if(tr[ls[p]].siz + tr[p].cnt >= rk) rt1 = ls[p],rt2 = p,rt3 = rs[p],ls[p] = rs[p] = 0;
        else rt1 = p,split(rs[p],rk-tr[ls[p]].siz-tr[p].cnt,rs[p],rt2,rt3);
        pushup(p);
    }
    inline int merge(int p,int q){
        if(!p || !q) return p ^ q;
        if(tr[p].pri < tr[q].pri){
            rs[p] = merge(rs[p],q),pushup(p);
            return p;
        }
        else {
            ls[q] = merge(p,ls[q]),pushup(q);
            return q;
        }
    }
    inline int query(int p,int val){
        if(!p) return 0;
        if(val < tr[p].val) return query(ls[p],val);
        else if(val == tr[p].val) return tr[ls[p]].siz;
        else return tr[ls[p]].siz + tr[p].cnt + query(rs[p],val);
    }
    inline int query_rank(int val){ 
        return query(root,val) + 1;
    }
    inline void insert(int val){
        int rk = query_rank(val);
        int rt1 = 0,rt2 = 0;
        split(root,rk,rt1,root,rt2);
        if(tr[root].val == val){
            tr[root].cnt++,tr[root].siz++;
            root = merge(merge(rt1,root),rt2);
        } 
        else {
            newnode(val);
            root = merge(merge(merge(rt1,tot),root),rt2);
        }
    }
    inline void erase(int val){
        int rk = query_rank(val);
        int rt1 = 0,rt2 = 0;
        split(root,rk,rt1,root,rt2);
        if(tr[root].val != val){
            root = merge(merge(rt1,root),rt2);
            return ;
        }
        if(tr[root].cnt > 1){
            tr[root].cnt--,tr[root].siz--;
            root = merge(merge(rt1,root),rt2);
        }
        else root = merge(rt1,rt2);
    }
    inline int query_val(int rk){
        if(rk < 1 || rk > tr[root].siz) return 0;
        int rt1 = 0,rt2 = 0,ans;
        split(root,rk,rt1,root,rt2);
        ans = tr[root].val;
        root = merge(merge(rt1,root),rt2);
        return ans;
    }
    inline int query_pre(int val){
        return query_val(query_rank(val) - 1);
    }
    inline int query_suf(int val){
        return query_val(query_rank(val + 1));
    } 
}T;
signed main(){
    n = read(),m = read();
    srand(time(0));
    for(int i = 1;i <= n;i++) a[i] = read(),T.insert(a[i]);
    int lst = 0,ans = 0;
    while(m--){
        int opt = read(),x = read() ^ lst;
        if(opt == 1) T.insert(x);
        else if(opt == 2) T.erase(x);
        else if(opt == 3) lst = T.query_rank(x),ans ^= lst;
        else if(opt == 4) lst = T.query_val(x),ans ^= lst;
        else if(opt == 5) lst = T.query_pre(x),ans ^= lst;
        else lst = T.query_suf(x),ans ^= lst;
    }
    write(ans);
    return 0;
}
2025/7/19 17:12
加载中...