题意
传送门 计蒜客 A1607 XOR
题解
不考虑 k k k 时,查询区间子序列异或最大值,即 Codeforces 1100F ,枚举右界,贪心地使位数高的线性基出现的位置尽可能地晚,最后处理包含在查询区间的线性基即可。
本题目标是最大化 k k k 与区间某个子序列异或和的按位或。考虑按位或的性质,若 k k k 第 i i i 位为 1 1 1,那么不论异或和是什么,结果的第 i i i 位都是 1 1 1。那么将所有 a i a_i ai 按位与上 k k k 的按位反转,问题就转换为求解最大化不考虑 k k k 的最大异或值。
#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 1E4 + 5, MAXLG = 27;
int T, N, Q, K, A[MAXN];
int B[MAXN][MAXLG], lst[MAXN][MAXLG];
void insert(int b[], int lst[], int x, int d)
{
for (int i = MAXLG - 1; i >= 0; --i)
if (x >> i & 1)
{
if (b[i] > 0)
{
if (lst[i] < d)
swap(b[i], x), swap(lst[i], d);
x ^= b[i];
}
else
{
b[i] = x, lst[i] = d;
break;
}
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> T;
while (T--)
{
cin >> N >> Q >> K;
for (int i = 0; i < N; ++i)
cin >> A[i], A[i] &= ~K;
memset(B, 0, sizeof(B));
for (int i = 0; i < N; ++i)
{
if (i > 0)
for (int j = MAXLG - 1; j >= 0; --j)
B[i][j] = B[i - 1][j], lst[i][j] = lst[i - 1][j];
insert(B[i], lst[i], A[i], i);
}
while (Q--)
{
int l, r;
cin >> l >> r;
--l, --r;
int res = 0;
for (int i = MAXLG - 1; i >= 0; --i)
if (!(res >> i & 1) && lst[r][i] >= l)
res ^= B[r][i];
res |= K;
cout << res << '\n';
}
}
return 0;
}