0
点赞
收藏
分享

微信扫一扫

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南):签到题A Matrix Equation(高斯消元求线性异或方程组自由元个数)

心存浪漫 2023-02-08 阅读 90


problem

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南):签到题A Matrix Equation(高斯消元求线性异或方程组自由元个数)_ci

  • 给出两个n*n的01矩阵,A和B
  • 定义两种运算,Z(i,j)=Xi行*Yj列相加%2,D(i,j)=X(i,j)*Y(i,j)
  • 求最多有多少个可能的矩阵C,满足A运算1C==B运算2C。

solution

思路:(明天接着补)

  • A和B相同等价于A(i,j)异或B(i,j)为0.
  • Xi行Yj列相加%2 等价于 Xi行Yj列相互异或(异或方程组)

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 255;
const int mod = 998244353;
LL pows(LL x, LL y, LL mod){
LL res = 1;
while(y>0){
if(y&1)res = res*x%mod;
x = x*x%mod;
y >>= 1;
}
return res%mod;
}

int n, a[maxn][maxn], b[maxn][maxn];
int t[maxn][maxn]; //增广矩阵
int Gauss(){
//用第i个式子消去第i个系数,求得倒三角
int cnt = 0;//表示行,这样在当前系数全为零时也能继续算下一个系数
for(int i = 0; i < n; i++){
int r = cnt;
while(r<n && !t[r][i])r++;
if(r==n)continue;
if(r!=cnt)swap(t[r],t[cnt]);

for(int j = cnt+1; j < n; j++){
if(t[j][i]!=0){
for(int k = i; k < n+1; k++)
t[j][k] ^= t[cnt][k];
}
}
cnt++;
}

//无解:存在(0,0,...,t)这样的行,且a!=0
//无穷解:出现(0,0,...,0)这样的行
int num = 0; //自由元
for(int i = 0; i < n; i++){
int ok = 1;
for(int j = 0; j < n; j++){
if(t[i][j] != 0){
ok = 0; break;
}
}
if(ok==1){
if(t[i][n]==0)num++;
if(t[i][n]!=0)return -1;
}
}
return num;
}

int main(){
cin>>n;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin>>a[i][j];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin>>b[i][j];
memcpy(t,a,sizeof(t));
LL ans = 1;
for(int i = 0; i < n; i++){
memcpy(t,a,sizeof(t));
for(int j = 0; j < n; j++)
t[j][j] = (a[j][j]-b[j][i]+2)%2;
int free = Gauss();
if(free==-1)continue;
ans = ans*pows(2,free,mod)%mod;
}
cout<<ans<<"\n";
return 0;
}


举报

相关推荐

0 条评论