题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5119
题目大意:给你n(n<= 40)个数,取任意一些数,异或和大于等于m的情况有多少种
思路:因为ai不会超过10^6,所以可以设一个上界1<<20,枚举每一个异或值。
dp[i][j]表示前i个数异或和为j的种类数
不取a[i]时,dp[i][j] += dp[i-1][j];
取a[i]时,dp[i][j^a[i]] += dp[i-1][j];
初始状态dp[0][0] = 1;
开long long
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 105
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define ULL unsigned long long
#define FOR(i , n) for(int i = 1 ; i<= n ; i ++)
typedef pair<int , int> pii;
#define INF 100000000
int t , n , m;
int ss = 1 << 20;
int a[50];
LL dp[50][1<<20];
int main()
{
scanf("%d" , &t);
int ncase = 1;
while(t--)
{
scanf("%d %d" , &n , &m);
for(int i = 1 ; i <= n ; i ++)
{
scanf("%d" , &a[i]);
}
mem(dp , 0);
dp[0][0] = 1;
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 0 ; j < ss ; j ++)
{
dp[i][j] += dp[i-1][j];
dp[i][j^a[i]] += dp[i-1][j];
}
}
LL ans = 0;
for(int j = m ; j < ss ; j ++)
{
ans += dp[n][j];
}
printf("Case #%d: %I64d\n" , ncase ++ , ans);
}
return 0;
}