1 条题解

  • 1
    @ 2023-3-14 14:01:37
    • int sum[MAXN + 5];:前缀异或和,sum[r]^sum[l-1]a[l]~a[r] 的异或和。
    • int f[MAXN + 5];f[i]a[1]~a[i] 所有子区间异或和中的最大值。
      • f[i] = max(f[i-1],以a[i]结尾的子区间的异或和最大值)
    • a[i] 结尾的子区间的异或和最大值:看看 sum[0]~sum[i-1] 哪个和 sum[i] 异或一下最大。
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXNODE = 400000 * 31; // 单词数*单词长度(最坏情况下节点数量)
    int tot, root, son[MAXNODE + 5][2];
    int tag[MAXNODE + 5]; // 存在几个单词
    void clearNode(int nId)
    {
        for (int i = 0; i < 2; i++)
            son[nId][i] = 0;
        tag[nId] = 0;
    }
    void ins(int s)
    {
        int now = root;
        for (int i = 30; i >= 0; i--)
        {
            // s的2^i位是多少
            int j = ((s >> i) & 1);
            if (!son[now][j])
            {
                son[now][j] = ++tot;
                clearNode(tot);
            }
            now = son[now][j];
        }
    }
    int check(int s)
    {
        int res = 0;
        int now = root;
        for (int i = 30; i >= 0; i--)
        {
            int j = ((s >> i) & 1);
            // 尽可能走不同的
            if (son[now][1 - j])
            {
                res += (1 << i);
                now = son[now][1 - j];
            }
            else
            {
                now = son[now][j];
            }
        }
        return res;
    }
    const int MAXN = 400000;
    int n;
    int a[MAXN + 5];
    int sum[MAXN + 5];
    int f[MAXN + 5];
    int g[MAXN + 5];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        // cal f[]
        tot = root = 1;
        clearNode(tot);
        sum[1] = a[1];
        for (int i = 2; i <= n; i++)
            sum[i] = sum[i - 1] ^ a[i];
        ins(0);
        f[0] = 0;
        for (int i = 1; i <= n; i++)
        {
            f[i] = max(f[i - 1], check(sum[i]));
            ins(sum[i]);
        }
        // cal g[]
        tot = root = 1;
        clearNode(tot);
        sum[n] = a[n];
        for (int i = n - 1; i >= 1; i--)
            sum[i] = sum[i + 1] ^ a[i];
        ins(0);
        g[n + 1] = 0;
        for (int i = n; i >= 1; i--)
        {
            g[i] = max(g[i + 1], check(sum[i]));
            ins(sum[i]);
        }
        // get ans
        int ans = 0;
        for (int i = 1; i <= n - 1; i++)
        {
            ans = max(ans, f[i] + g[i + 1]);
        }
        cout << ans << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    693
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    36
    已通过
    16
    上传者