社区讨论

关于数据范围,求巨佬解答,必关!!!

P13874[蓝桥杯 2024 省 Java/Python A] 最大异或结点参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mlhelhii
此快照首次捕获于
2026/02/11 10:21
上周
此快照最后确认于
2026/02/12 20:45
7 天前
查看原帖
rt,我一开始写的代码如下:
CPP
#include <bits/stdc++.h>
using namespace std;
int n, res[111111];
vector<int> g[111111];
int ch[100003*32][2], idx;
int cnt[100003*32];
void insert(int x){
    int q = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        if (!ch[q][j]) ch[q][j] = ++idx;
        q = ch[q][j];
        cnt[q] ++;
    }
}
int query(int x){
    int p = 0;
    int ans = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        if (ch[p][!j]){
            ans += (1 << i);
            p = ch[p][!j];
        }
        else p = ch[p][j];
    }
    return ans;
}
void erase(int x){
    int p = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        int p2 = p;
        p = ch[p][j];
        cnt[p] --;
        if (cnt[p] == 0) ch[p2][j] = 0;
    }
}
int main(){
    cin >> n;
    for (int i = 1; i <= n; i ++){
        cin >> res[i];
        insert(res[i]);
    }
    for (int i = 1; i <= n; i ++){
        int fa; cin >> fa;
        if (fa == -1) continue;
        g[fa+1].push_back(i);
        g[i].push_back(fa+1);
    }
    int ans = 0;
    for (int i = 1; i <= n; i ++){
        for (auto j : g[i]){
            erase(res[j]);
        }
        ans = max(ans, query(res[i]));
        for (auto j : g[i]){
            insert(res[j]);
        }
    }
    cout << ans;
    return 0;
}
喜提RE,55pts。
然而:
CPP
#include <bits/stdc++.h>
using namespace std;
int n, res[111111];
vector<int> g[111111];
int ch[1000031*32][2], idx;
int cnt[1000031*32];
void insert(int x){
    int q = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        if (!ch[q][j]) ch[q][j] = ++idx;
        q = ch[q][j];
        cnt[q] ++;
    }
}
int query(int x){
    int p = 0;
    int ans = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        if (ch[p][!j]){
            ans += (1 << i);
            p = ch[p][!j];
        }
        else p = ch[p][j];
    }
    return ans;
}
void erase(int x){
    int p = 0;
    for (int i = 30; i >= 0; i --){
        int j = (x >> i) & 1;
        int p2 = p;
        p = ch[p][j];
        cnt[p] --;
        if (cnt[p] == 0) ch[p2][j] = 0;
    }
}
int main(){
    cin >> n;
    for (int i = 1; i <= n; i ++){
        cin >> res[i];
        insert(res[i]);
    }
    for (int i = 1; i <= n; i ++){
        int fa; cin >> fa;
        if (fa == -1) continue;
        g[fa+1].push_back(i);
        g[i].push_back(fa+1);
    }
    int ans = 0;
    for (int i = 1; i <= n; i ++){
        for (auto j : g[i]){
            erase(res[j]);
        }
        ans = max(ans, query(res[i]));
        for (auto j : g[i]){
            insert(res[j]);
        }
    }
    cout << ans;
    return 0;
}
就AC了???
可以发现,两段代码的唯一区别就是ch数组和cnt数组的大小不同。但是,经过理论计算,数组所需的大小仅仅需要 105×3210^5\times32 即可,AC代码却开了将近 106×3210^6\times32 的大小。
求巨佬解答,必关!!!

回复

2 条回复,欢迎继续交流。

正在加载回复...