这道题可以说是学了 bitset b i t s e t 后做的第一题
但是还是 ylsoi y l s o i 手把手教我做的.. 我是真的菜…
首先这个题有个很坑的地方 它的数据是有问题的,读入每个数字的时候可能没有 n n 个,你只能边读边处理,存下来的话你会莫名的!!!
首先看这个问题,子集算术和想到了什么
背包问题不就计算了子集元素算术和吗
但是这个题直接跑背包发现复杂度太大了
但是这个题转移有个很妙的性质 因为要求的是答案的异或和
可以写出转移方程 f[x]⊕=f[x−a[i]] f [ x ] ⊕ = f [ x − a [ i ] ]
值域又不是很大 最后的结果只和答案的奇偶性有关
转移还用了位运算
我们不难想到用 bitset b i t s e t 来优化背包
每次转移的时候把 f f 和异或一下就好了
复杂度 O(n∑aω) O ( n ∑ a ω )
Codes
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
bitset<N> f;
int a[N], n;
int main() {
#ifndef ONLINE_JUDGE
freopen("3687.in", "r", stdin);
freopen("3687.out", "w", stdout);
#endif
scanf("%d", &n);
int ans = 0; f[0] = 1;
for(int i = 1, u; i <= n; ++ i) {
scanf("%d", &u);
f ^= (f << u);
}
for(int i = 0; i < N; ++ i)
ans ^= f[i] * i;
cout << ans << endl;
return 0;
}