隐藏
「LibreOJ113」最大异或和 - 线性基 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「LibreOJ113」最大异或和 - 线性基

题目大意

    给由$n$个数组成的一个可重集$S$,求一个集合$T\subseteq S$ ,使$T_1\,xor\,T_2\,xor\ldots\,xor\,T_{|T|}$最大。


题目分析

线性基模板题。
学习笔记待补坑。(2017/12/18 update. 学习笔记已补坑)


代码

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

typedef long long LL;

inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}

const int MAX_BASE=50;

struct Linear_Bases {
LL b[MAX_BASE+5];
void build(vector<LL> a) {
for(LL num:a)
for(int j=MAX_BASE; j>=0; j--)
if(num>>j&1) {
if(b[j]) { //该位存在基
num^=b[j];
continue;
}
b[j]=num;
for(int k=j-1; k>=0; k--)if(b[j]>>k&1)b[j]^=b[k];
for(int k=j+1; k<=MAX_BASE; k++)if(b[k]>>j&1)b[k]^=b[j];
break;
}
}
LL cal() { //最大异或和
LL ans=0;
for(int i=0; i<=MAX_BASE; i++)ans^=b[i];
return ans;
}
} lb;

int n;
vector<LL>a;

int main() {
n=Get_Int();
for(int i=1; i<=n; i++)a.push_back(Get_Int());
lb.build(a);
printf("%lld\n",lb.cal());
return 0;
}
姥爷们赏瓶冰阔落吧~