按位考虑的话,相当于是每一位在 (mod 2) 意义下做循环卷积,该位上有一个 (G*F=T) ,其中 (F,G) 给定(每一位的 (F) 一样)。
我们尝试找这个 (F) 在循环卷积意义下的逆。
首先我们不妨设 ([x^0y^0] F= 1) 可以通过让所有位置循环的移动来实现这件事。
考虑 (F^2) ,考虑两个为 (1) 的位置 ((x_1,y_1)),((x_2,y_2)) 显然 ((x_2,y_2), (x_1,y_1)) 也会有贡献,因为是异或这两个抵消掉了。
于是原来的 ((x,y)) 会在取平方后变成 ((2x,2y)) 。
容易发现 (F^{(2^k)}) 恰好等于 (1)。
于是 (F^{2^k-1}) 是 (F) 的一个逆。
而如果有多个逆,则必定存在一个非 (0) 的 (G) 使得 (GF=0) ,而此时 (G F^{2^k}= 0) ,故 (G = 0) 。
于是这个逆是唯一的。故原题解唯一,暴力乘上 (F^{2^k}) 即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int k, n, vec;
const int N = 1<<9;
ll a[N][N], b[N][N];
int x[N], y[N];
int main()
{
cin >> k;n=1<<k;
for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%lld",&a[i][j]);
cin >> vec;
for(int i=0;i<vec;i++){
scanf("%d%d",&x[i],&y[i]);
}
for(int i=vec-1;~i;i--){
x[i]-=x[0],y[i]-=y[0];
}
for(int t=0;t<k;t++){
for(int i=0;i<n;i++)for(int j=0;j<n;j++)b[i][j]=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int q=0;q<vec;q++){
int nxtx=(i+x[q])&(n-1), nxty=(j+y[q])&(n-1);
b[nxtx][nxty]^=a[i][j];
}
}
}
for(int i=0;i<n;i++)for(int j=0;j<n;j++)a[i][j]=b[i][j];
for(int i=0;i<vec;i++)x[i]=(x[i]*2)&(n-1),y[i]=(y[i]*2)&(n-1);
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j])ans++;
}
}
cout << ans << endl;
}