题目链接:#113. 最大异或和
题目描述
这是一道模板题。
给由 (n) 个数组成的一个可重集 (S),每次给定一个数 (k),求一个集合 (T subseteq S),使得集合 (T) 在 (S) 的所有非空子集的不同的异或和中,其异或和 (T_1 xor T_2 xor ... xor T_{|T|}) 是第 (k) 小的。
输入格式
第一行一个数 (n)。
第二行 (n) 个数,表示集合 (S)。
第三行一个数 (m),表示询问次数。
第四行 (m) 个数,表示每一次询问的 (k)。
输出格式
输出 (m) 行,对应每一次询问的答案,第 (k) 小的异或和。如果集合 (S) 的所有非空子集中,不同的异或和数量不足 (k),输出 (-1)。
样例
样例输入
3 1 2 3 5 1 2 3 4 5
样例输出
0 1 2 3 -1
数据范围与提示
(1le n,mle 10^5, 0le S_ile 2^{50})
题解
线性基 贪心
线性基模板题。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
using ll = long long;
const int maxn = 5e5 + 5;
const int maxbit = 63; // long long 最大 2^63 - 1. 最多 63 位. 用数组表示为 0 ~ 62.
ll p[maxbit];
void add(ll x) {
for(int i = maxbit - 1; i >= 0; --i) {
if((x >> i) & 1) {
if(p[i] == 0) {
p[i] = x;
break;
}
x ^= p[i];
}
}
}
int main() {
std::ios::sync_with_stdio(false);
int n;
cin >> n;
for(int i = 1; i <= n; ++i) {
ll x;
cin >> x;
add(x);
}
ll ans = 0;
for(int i = maxbit - 1; i >= 0; --i) {
if((ans ^ p[i]) > ans) {
ans ^= p[i];
}
}
cout << ans << endl;
return 0;
}