求n个数,取出其中若干个使其异或和大于等于m的方案数。
有个简单的优化就是把当前异或到得所有的结果存起来。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const long long maxn = 1024*1024;
int dp[maxn][42];
int num[maxn], cnt;
bool vis[maxn];
int a[44];
int main()
{
int n,m;
int t;
int kase=0;
scanf("%d",&t);
while(t--) {
scanf ("%d%d",&n,&m);
memset (vis, 0, sizeof vis);
cnt = 0;
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
memset (dp, 0, sizeof dp);
dp[0][0]=1;
num[cnt++] = 0;
vis[0] = 1;
for(int i=1;i<=n;i++) {
for(int j=0;j<cnt;j++)
dp[num[j]][i]=dp[num[j]][i-1];
for(int j=0;j<cnt;j++) {
dp[num[j]^a[i]][i]+=dp[num[j]][i-1];
if (!vis[num[j]^a[i]])
vis[num[j]^a[i]] = 1, num[cnt++] = num[j]^a[i];
}
}
long long ans=0;
for(int j=m;j<maxn;j++)
ans+=dp[j][n];
printf("Case #%d: ", ++kase);
printf("%lld\n",ans);
}
return 0;
}