题意:

给你n个数字, 和m,让你求从这n个数字里面抽取若干个数字, 其异或和不小于m的方案数。

题解:

m的取值范围不超过 1000000

建一个二维的dp数组,通过滚动来进行dp

状态转移方程式为:dp[i%2][j] = dp[(i-1)%2][j] + dp[(i-1)%2][j^num[i]];

dp[(i-1)%2][j] 代表不取num[i]的的异或和为j的方案数

dp[(i-1)%2][j^num[i]]   代表取num[i]的的异或和为j的方案数   j^num[i]^num[i] = j

/*
Algorithm:
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define mod 1e9 + 7
#define line printf("--------------\n");
using namespace std;
ll dp[2][2*1000005];
int num[45];
int main() {
    int t;
    cin>>t;
    int cc = 1;
    while(t--) {
        int n, m;
        cin>>n>>m;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &num[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%2][j] = dp[(i-1)%2][j] + dp[(i-1)%2][j^num[i]];
//                cout<<dp[i%2][j]<<endl;
            }
        }
        ll sum = 0;
        for(int i = m; i < 1<<20; i++) {
            sum+=dp[n % 2][i]; 
        }
        printf("Case #%d: ",cc++);
        cout<<sum<<endl;
    }


    return 0;
}