题目链接:#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}\)
题解
线性基 贪心
线性基模板题。
#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; }