SD 一轮集训 day4 弦形袋鼠

     可以发现把每一个 a[i] * b[i] 加到矩阵里去,就相当于 把一个 1*m 的向量伸缩后变成 n个再加到矩阵里去,所以答案就是远=原矩阵中线性线性无关组的个数。

 (而且好像一个矩阵横着消元和竖着消元 ,得到的线性无关组个数是一样的啊)

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int ha=1e9+7,maxn=205;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}

inline int ksm(int x,int y){
	int an=1;
	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
	return an;
}

int a[maxn][maxn],n,m;

inline int solve(){
	int i=1,j=1,pos;
	while(i<=n&&j<=m){
		pos=0;
		for(int k=i;k<=n;k++) if(a[k][j]){ pos=k; break;}
		
		if(!pos){ j++; continue;}
		
		if(pos!=i) for(int k=j;k<=m;k++) swap(a[pos][k],a[i][k]);
		
		
		int inv=ksm(a[i][j],ha-2),tmp;
		for(int k=i+1;k<=n;k++) if(a[k][j]){
			tmp=inv*(ll)a[k][j]%ha;
			for(int l=j;l<=m;l++) ADD(a[k][l],ha-a[i][l]*(ll)tmp%ha);
		}
		
		i++,j++;
	}
	
	return i-1;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++) scanf("%d",&a[i][j]),ADD(a[i][j],ha);
	
	printf("%d
",solve());
	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/9176033.html