[CF282E] Sausage Maximization

[CF282E] Sausage Maximization - Trie

Description

给定一个序列,记 (a) 为序列任意前缀的异或和,(b) 为序列任意后缀的异或和,求 (a) 异或 (b) 的最大值,前缀和后缀可以为空。

Solution

如果前缀和后缀相交了,那么相交的那段等于不存在,所以不用考虑相交

转化为,选出一个子串,使得这个子串的异或和与总的异或和的异或最大

利用 Trie 树维护,每次插入一个前缀和,并查询与前面的所有前缀形成的最大值

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 200005;
const int B = 50;

struct Trie
{
    struct Node
    {
        Node *left;
        Node *right;
        Node() : left(nullptr), right(nullptr) {}
    } * root;

    Trie()
    {
        root = new Node;
    }

    void Insert(int val)
    {
        Node *p = root;
        for (int i = B - 1; i >= 0; i--)
        {
            if ((val >> i) & 1)
            {
                if (p->right == nullptr)
                    p->right = new Node();
                p = p->right;
            }
            else
            {
                if (p->left == nullptr)
                    p->left = new Node();
                p = p->left;
            }
        }
    }

    int QueryXorMax(int val)
    {
        Node *p = root;
        int ans = 0;
        for (int i = B - 1; i >= 0; i--)
        {
            int now = (val >> i) & 1;
            if (now)
            {
                if (p->left)
                {
                    p = p->left;
                    ans |= 1ll << i;
                }
                else
                {
                    p = p->right;
                }
            }
            else
            {
                if (p->right)
                {
                    p = p->right;
                    ans |= 1ll << i;
                }
                else
                {
                    p = p->left;
                }
            }
        }
        return ans;
    }
};

int n;

signed main()
{
    ios::sync_with_stdio(false);

    cin >> n;
    vector<int> a(n + 2);

    for (int i = 1; i <= n; i++)
        cin >> a[i];

    int xor_all = 0;
    for (int i = 1; i <= n; i++)
        xor_all ^= a[i];

    Trie trie;
    trie.Insert(0);

    int xor_pre = 0;

    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        xor_pre ^= a[i];
        trie.Insert(xor_pre);

        int xor_val = xor_pre ^ xor_all;
        int tans = trie.QueryXorMax(xor_val);
        ans = max(ans, tans);
    }

    cout << ans << endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14377479.html