首页 > 代码库 > [LOJ#113]最大异或和

[LOJ#113]最大异或和

[LOJ#113]最大异或和

试题描述

这是一道模板题。

给由 n 个数组成的一个可重集 S,求一个集合 T?S,使 T1 xor T2 xor … xor T|T| 最大

输入

第一行一个数 n
第二行 n 个数,表示集合 S

输出

T1 xor T2 xor … xor T|T| 的最大值。

输入示例

3
5 2 8

输出示例

15

数据规模及约定

1n50,0S?i??2?50??

题解

练一下线性基模板。

果然打错了好多地方。。。

首先在插入一个元素的时候,要注意只有最高位是 1 并且这个 1 在当前位的时候才尝试插入。

然后在最终算答案时,要从高位向地位枚举。。。

线性基的各种性质可以去 http://blog.csdn.net/qaq__qaq/article/details/53812883 学习一下。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define LL long long

const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
	if(Head == Tail) {
		int l = fread(buffer, 1, BufferSize, stdin);
		Tail = (Head = buffer) + l;
	}
	return *Head++;
}
LL read() {
	LL x = 0, f = 1; char c = Getchar();
	while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = Getchar(); }
	while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = Getchar(); }
	return x * f;
}

#define maxn 55

int n;
LL bit[maxn];

int main() {
	n = read();
	for(int i = 1; i <= n; i++) {
		LL a = read();
		for(int j = maxn - 1; j; j--) if(a >> j-1 & 1) {
			if(!bit[j]){ bit[j] = a; break; }
			else a ^= bit[j];
		}
	}
	
	LL ans = 0;
	for(int i = maxn - 1; i; i--) if((ans ^ bit[i]) > ans) ans ^= bit[i];
	printf("%lld\n", ans);
	
	return 0;
}

我真是太 zz 了。。。

[LOJ#113]最大异或和