题目:求子集的算术和的异或和
题解:
按照正常思路是维护一个dp[i],表示和为i的组合有多少个,然后如果dp[i]%2==1则ans^i就可以了··然而复杂度为sum*n,果断T
考虑用一个布尔数组表示dp[i],dp[i]为1表示和为i的组合的数量为奇数,0为偶数
然后每输入一个数x,可以用dp[i]更新dp[i+x],即dp[i+x]=(dp[i+x]+dp[i])%2,既然我们用的是布尔数组,可以利用位运算+bitset,来一次性更新所有的i而不用一一枚举sum,即dp=dp^(dp<<x).
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
#include<bitset>
using namespace std;
const int N=2e6+5;
bitset<N>dp;
int ans=0,a,tot,n;
int main()
{
//freopen("a.in","r",stdin);
scanf("%d",&n);
dp[0]=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
tot+=a;dp^=(dp<<a);
}
for(int i=0;i<=tot;i++)
if(dp[i]) ans^=i;
cout<<ans<<endl;
return 0;
}