ABC141F

假如某一位有奇数个 \(1\),那么无论怎么拆分这一位都会有贡献。

那么先把这些贡献加起来,然后去除掉这些位。

发现剩下来的位都是偶数个 \(1\),也就意味着,无论怎么拆分,拆分出来的两个数的肯定相等。

那么就是求从一些数中选出若干个数,使得它们的异或和最大。

那么这个就是可以用线性基解决的。

时间复杂度 \(\mathcal O(n\log w)\)

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005, M = 65;
int n;
ll a[N], B[M], cnt[M];
ll ans;

void insert(ll x) {
	for (int i = 59; ~i; --i) if (x >> i & 1) {
		if (B[i]) x ^= B[i];
		else return B[i] = x, void();
	}
}

ll query() {
	ll res = 0;
	for (int i = 59; ~i; --i)
		res = max(res, res ^ B[i]);
	return res;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		for (int j = 59; ~j; --j)
			if (a[i] >> j & 1) ++cnt[j];
	}
	for (int i = 59; ~i; --i) if (cnt[i] & 1) {
		ans |= (1ll << i);
		for (int j = 1; j <= n; ++j)
			if (a[j] >> i & 1) a[j] ^= (1ll << i);
	}
	for (int i = 1; i <= n; ++i) insert(a[i]);
	printf("%lld", query() * 2 + ans);
	return 0;
}
posted @ 2022-10-26 20:28  Kobe303  阅读(16)  评论(0编辑  收藏  举报