这题用01-Trie能过吗?

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

Azurite @ 2024-09-15 08:41:55

普通平衡树模板题成功用01-Trie通过了且效率很高,遂尝试挑战数据加强版.不期遇RE挡我AC路,不禁发问01-Trie是否在数据加强的新形势下发挥它应有的作用? 代码如下,求调

#include <stdio.h>
int n, m;
int trie[100005 * 33][2], tot, cnt[100005 * 33], fa[100005 * 33], last, ans;
void insert(int x){
    int u = 0;
    for(int i = 31; i >= 0; i--){
        int z = (x >> i) & 1;
        if(!trie[u][z])
            trie[u][z] = ++tot, fa[tot] = u;
        u = trie[u][z];
        cnt[u]++;
    }
}
void del(int x){
    int u = 0;
    for(int i = 31; i >= 0; i--){
        int z = (x >> i) & 1;
        u = trie[u][z];
        cnt[u]--;
    }
}
int getrank(int x){
    int u = 0;
    int res = 1;
    for(int i = 31; i >= 0; i--){
        int z = (x >> i) & 1;
        if(!trie[u][z])
            trie[u][z] = ++tot, fa[tot] = u;
        if(z == 1 && cnt[trie[u][0]])
            res += cnt[trie[u][0]];
        u = trie[u][z];
    }
    return res;
}
int query(int x){
    int u = 0;
    int res = 0;
    for(int i = 31; i >= 0; i--){
        if(cnt[trie[u][0]] >= x)
            u = trie[u][0];
        else
            x -= cnt[trie[u][0]], u = trie[u][1], res += (1 << i);
    }
    return res;
}
int prev(int x){
    int u = 0, i;
    int res = x;
    for(i = 31; i >= 0; i--){
        int z = (x >> i) & 1;
        if(!trie[u][z])
            trie[u][z] = ++tot, fa[tot] = u;
        u = trie[u][z];
    }
    int mask = -1;
    while(trie[fa[u]][0] == u || !cnt[trie[fa[u]][0]]){
        u = fa[u];
        mask <<= 1;
        res &= mask;
        i++;
    }
    mask <<= 1;
    res &= mask;
    u = trie[fa[u]][0];
    for(; i >= 0; i--){
        if(cnt[trie[u][1]])
            u = trie[u][1], res += (1 << i);
        else
            u = trie[u][0];
    }
    return res;
}
int next(int x){
    int u = 0, i;
    int res = x;
    for(i = 31; i >= 0; i--){
        int z = (x >> i) & 1;
        if(!trie[u][z])
            trie[u][z] = ++tot, fa[tot] = u;
        u = trie[u][z];
    }
    int mask = -1;
    while(trie[fa[u]][1] == u || !cnt[trie[fa[u]][1]]){
        u = fa[u];
        mask <<= 1;
        res &= mask;
        i++;
    }
    mask <<= 1;
    res &= mask;
    u = trie[fa[u]][1], res += (1 << i + 1);
    for(; i >= 0; i--){
        if(cnt[trie[u][0]])
            u = trie[u][0];
        else
            u = trie[u][1], res += (1 << i);
    }
    return res;
}
int main(void){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++){
        int a;
        scanf("%d", &a);
        insert(a);
    }
    for(int i = 1; i <= m; i++){
        int opt, x;
        scanf("%d %d", &opt, &x);
        x ^= last;
        if(opt == 1)
            insert(x);
        else if(opt == 2)
            del(x);
        else if(opt == 3){
            last = getrank(x);
            ans ^= last;
        }
        else if(opt == 4){
            last = query(x);
            ans ^= last;
        }
        else if(opt == 5){
            last = prev(x);
            ans ^= last;
        }
        else{
            last = next(x);
            ans ^= last;
        }
    }
    printf("%d", ans);
    return 0;
}

by zjpwdyf @ 2024-09-15 08:59:43

@Azurite 由于此题的毒瘤空间限制,0-1 Trie 会 MLE(如果开小了就会 RE),但是存在优化方案,见题解区第一篇


by Azurite @ 2024-09-16 23:39:23

@zjpwdyf thx


|