题目大意:有n个m元组
题解:观察FWHT中的Haramard矩阵,
为了方便起见,设
所以有
设向量
即如果
现在固定x=t,考虑每一个m元组的生成函数
只要其中出现了一次
对于式子中的
所以可以发现,
由于FWHT是一个线性运算,所以可以把每个m元组,甚至每个m元组中的每一项的贡献单独计算并相加,所以就可以直接先把所有项全部加起来然后直接做一次FWHT得出答案。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1<<20,mo=1e9+7;
void FWHT(int *arr,int N,int inv_flg=0)
{
for (int k=1;k<N;k<<=1)
for (int i=0;i<N;i+=(k<<1))
for (int j=0;j<k;j++)
{
if (inv_flg)
{
int x=arr[i+j],y=arr[i+j+k];
arr[i+j]=(x+y)/2;
arr[i+j+k]=(x-y)/2;
}
else
{
int x=arr[i+j],y=arr[i+j+k];
arr[i+j]=x+y;
arr[i+j+k]=x-y;
}
}
}
int f[maxn];
int a[11];
int n,m,k,N;
void DFS(int x,int res,int p)
{
if (x==m)
{
f[res]+=p;
return;
}
DFS(x+1,res,p);
DFS(x+1,res^a[x],-p);
}
int main()
{
while (scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for (int i=0;i<(1<<k);i++) f[i]=0;
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++) scanf("%d",&a[j]);
DFS(0,0,1);
}
FWHT(f,1<<k);
int res=0;
for (int i=0,p=1;i<(1<<k);i++,p=p*3ll%mo)
res^=(long long)p*(f[i]>>m)%mo;
printf("%d\n",res);
}
}