题目链接:#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
数据范围与提示
$1\le n,m\le 10^5, 0\le S_i\le 2^{50}$
题解
线性基 贪心
线性基模板题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <bits/stdc++.h> using namespace std; typedef long long ll; using ll = long long; const int maxn = 5e5 + 5; const int maxbit = 63;
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; }
|