0%

LOJ #113. 最大异或和 (线性基)

题目链接:#113. 最大异或和

题目描述

这是一道模板题。

给由 n 个数组成的一个可重集 S,每次给定一个数 k,求一个集合 TS,使得集合 TS 的所有非空子集的不同的异或和中,其异或和 T1xorT2xorxorT|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

数据范围与提示

1n,m105,0Si250

题解

线性基 贪心

线性基模板题。

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; // 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;
}

欢迎关注我的其它发布渠道

Powered By Valine
v1.5.2