di,j表示前i个数获得异或为j的方案数,则
di,j = di-1,j + di-1,j^a[i] .
1e6 < 2 ^ 20, 故异或最大可以到2^20.有 40 个数,总共差不多4*10^7的空间,没必要滚动。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int t,n,m,dp[41][(1<<20) + 5],a[50],cas;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++)
scanf("%d",a+i);
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
for(int i = 1;i<=n;i++)
for(int j = 0;j<(1<<20);j++)
dp[i][j] = dp[i-1][j] + dp[i-1][j^a[i]];
long long ans= 0;
for(int j = m;j<(1<<20);j++)
ans += dp[n][j];
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}