题目大意
求n个数的子序列的最大异或和。
解题思路
求出n个数的线性基并排序,然后将k二进制异或上线性基中对应的代表元素即可。
代码
const int maxn = 2e5+10;
ll arr[maxn];
vector<ll> b; //b中存的每个二进制位的代表元素
void insert(ll x) { //设x在线性基中(不是原来的数字)二进制表示为1的最高位为y
for (auto v : b) x = min(x, x^v); //x的二进制位中小于y的二进制位不能和其他代表元素同为1
for (auto &v : b) v = min(v, v^x); //b中元素的二进制位中第y位的二进制位不能和x同为1
if (x) b.push_back(x);
}
int main(void) {
IOS; int kase = 0;
int __; cin >> __;
while(__--) {
cout << "Case #" << ++kase << ":" << endl;
int n; cin >> n;
b.clear();
for (int i = 1; i<= n; ++i) {
cin >> arr[i];
insert(arr[i]);
}
sort(b.begin(), b.end());
int q; cin >> q;
while(q--) {
ll k; cin >> k;
if (b.size()<n) --k;
if (k+1>1LL<<b.size()) cout << -1 << endl;
else {
ll sum = 0;
for (int i = 0; i<b.size(); ++i)
if (k>>i&1) sum ^= b[i];
cout << sum << endl;
}
}
}
return 0;
}