A、Matrix Equation (2020icpc济南)
作者:互联网
A、Matrix Equation
题意:
给定两个 \(n\times n\) 的\(01\)矩阵\(A\),\(B\),求\(01\)矩阵 \(C\) 的种数,其中 \(C\) 满足 \(A\times C = B\odot C\) 。
设 \(Z = X\times Y\) ,即表示 \({Z_{i,j}} = (\sum^{n}_{k=1} X_{i,k}Y_{k,j} ) mod 2\) 。
设 \(S = X\odot Y\) ,即表示 \({S_{i,j}} = X_{i,j}Y_{i,j}\) 。
思路:
首先,考虑 \(C\) 矩阵的元素只由$ 0 1 $组成,每个 \(C\) 矩阵中的未知数都可以通过 \(A、B\) 两个矩阵表示成一些方程组,考虑高斯消元法,那么即如果某个位置都未知数是确定的,则方法数不变,如果是自由变元,即不能确定的,那么方法数$ \times 2$(因为该位置有两种可能取值,即0或1)。
在使用高斯消元法求解过程中,我们发现如果设置 \(n\times n\) 个未知量,那么时间复杂度必定会爆炸,接下来考虑上面都式子,我们发现两个式子都是列独立的,即 \(C\) 中每一列的所有未知量可以单独构成n个方程组,这一列与其他列的未知量是无关的,可以推出方乘(以第一列为例)
\(\begin{cases}A_{1,1}\times C_{1,1}+A_{1,2}\times C_{2,1}+ ...+A_{1,n}\times C_{n,1} = B_{1,1}\times C_{1,1}\\A_{2,1}\times C_{1,1}+A_{2,2}\times C_{2,1}+ ...+A_{2,n}\times C_{n,1} = B_{2,1}\times C_{2,1}\\ ......\\ ......\\ A_{3,1}\times C_{1,1}+A_{3,2}\times C_{2,1}+ ...+A_{3,n}\times C_{n,1} = B_{n,1}\times C_{n,1} \\\end{cases}\)
然后把右边移动到左边,由左边各未知数的系数作为增广矩阵,最后用高斯消元法,一列列的求出各列中自由变元的数量即可。
最终答案即是 \(2^{ans} \ mod \ 998244353\) 。
代码:
const int N = 205;
const ll mod=998244353;
ll A[N][N],B[N][N];
ll ma[N][N];
ll x[N];
ll n;
bool freeX[N];
//有equ个方程,var个变元。增广矩阵行数为equ,列数为var+1
ll Gauss(ll equ, ll val){
ll r = 1, ans = 0;
for(int c = 1; c <= n; c++)
{
ll now = r;
for(int i = r; i <= n; i++)
{
if(ma[i][c])
{
now = i;
break;
}
}
if(!ma[now][c])
{
ans++;
continue;
}
for(int i = c; i <= n; i++)
swap(ma[now][i], ma[r][i]);
//Print(mc);
for(int i = r + 1; i <= n; i++)
{
if(ma[i][c])
for(int j = c; j <= n; j++)
ma[i][j] ^= ma[r][j];
}
//Print(mc);
r++;
}
return ans;
}
ll qpow(ll a,ll b,ll mod)
{
ll ans=1;
while(b){
if(b&1){
ans=ans*a;
ans=ans%mod;
}
a=a*a;
a=a%mod;
b/=2;
}
return ans%mod;
}
void init()
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ma[i][j]=A[i][j];
}
}
}
int main()
{
ll equ,var; //equ个方程,var个变元
scanf("%lld",&n);
equ=n;
var=n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%lld",&A[i][j]);
ma[i][j]=A[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%lld",&B[i][j]);
}
}
ll ans=1;
for(int j=1;j<=n;j++)
{
init();
for(int i=1;i<=n;i++){
ma[i][i]=(A[i][i]-B[i][j]+2)%2;
ma[i][n+1]=0;
}
ll freenum=Gauss(equ,var);
if(freenum==-1) continue;
//cout<<freenum<<endl;
ans*=qpow(2,freenum,998244353);
ans=ans%mod;
}
printf("%lld\n",ans);
return 0;
}
标签:Matrix,...+,Equation,矩阵,times,2020icpc,ll,高斯消,mod 来源: https://www.cnblogs.com/ha-chuochuo/p/14300360.html