[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;
}