思路:用字典树来统计异或和大于M的种数就行了
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1100010;
const int INF=0x3f3f3f3f;
const int maxc=2;
const int BIT=21;
int cas=1,T;
int n,m,k[50],kk[50],half;
int ch[N*20][maxc],si[N*20];
void init()
{
memset(ch[0],0,sizeof(ch[0]));
si[0]=1;
}
void insert(int s)
{
int u=0;
for(int i=BIT-1;i>=0;i--)
{
int c=(s&(1<<i)?1:0);
if(!ch[u][c])
{
memset(ch[si[0]],0,sizeof(ch[0]));
si[si[0]]=0;
ch[u][c]=si[0]++;
}
u=ch[u][c];
si[u]++;
}
}
int find(int s)
{
int u=0,ans=0;
for(int i=BIT-1;i>=0;i--)
{
int c=(s&(1<<i)?1:0);
if(m&(1<<i))
{
if(!ch[u][!c]) return ans;
u=ch[u][!c];
}
else
{
if(ch[u][!c]) ans+=si[ch[u][!c]];
if(!ch[u][c]) return ans;
u=ch[u][c];
}
}
return ans+si[u];
}
int main()
{
//freopen("1.in","w",stdout);
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
half=n/2;
int r=n-half;
//printf("%d %d\n",half,r);
for(int i=0;i<half;i++) scanf("%d",&k[i]);
for(int i=0;i<r;i++) scanf("%d",&kk[i]);
LL ans=0;
for(int i=0;i< 1<<half;i++)
{
int sum=0;
for(int j=0;j<half;j++) if(i&(1<<j)) sum^=k[j];
//printf("s:%d\n",sum);
insert(sum);
}
for(int i=0;i< 1<<r;i++)
{
int sum=0;
for(int j=0;j<r;j++) if(i&(1<<j)) sum^=kk[j];
//printf("sum:%d\n",sum);
ans+=find(sum);
}
printf("Case #%d: %lld\n",cas++,ans);
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}