2016CampDay7problemA.ABBA

链接:https://alpha.icpc-camp.org/submissions/new#(需要账号)

分析:求矩阵的秩,直接高斯消元会爆longlong,用浮点会爆精度,所以可以用取多个模做模意义下的高斯消元,然后取最大的秩。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=210;
const int MAX=151;
const int mod=100000000;
const int MOD1=100000007;
const int MOD2=100000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000009;
const ll INF=10000000010;
typedef double db;
typedef unsigned long long ull;
int n,m;
ll a[N][N],d[N][N];
ll pri[10]={0,1000000007,1000000009,258280327,998244353,1004535809};
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y) {
    if (!b) { d=a;x=1;y=0; }
    else { ex_gcd(b,a%b,d,y,x);y-=x*(a/b); }
}
ll inv(ll a,ll n) {
    ll d,x,y;
    ex_gcd(a,n,d,x,y);
    return d==1 ? (x+n)%n:-1;
}
int guass(ll M) {
    int i,j,k,x=1,y=1,w,mx;
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++) d[i][j]=a[i][j];
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
        if (d[i][j]<0) d[i][j]=(d[i][j]%M+M)%M;
    while (1) {
        if (x>n||y>m) break ;
        mx=d[x][y];w=x;
        for (i=x+1;i<=n;i++)
        if (d[i][y]>mx) { mx=d[i][y];w=i; }
        if (mx==0) { y++;continue ; }
        for (i=y;i<=m;i++) swap(d[x][i],d[w][i]);
        for (i=x+1;i<=n;i++)
        if (d[i][y]) {
            k=M-(d[i][y]*inv(d[x][y],M)%M);
            for (j=y;j<=m;j++) d[i][j]=((d[i][j]+d[x][j]*k%M)%M+M)%M;
        }
        x++;
    }
    return x-1;
}
int main()
{
    int i,j,ans=0;
    scanf("%d%d", &n, &m);
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
        scanf("%lld", &a[i][j]);
    for (i=1;i<=5;i++) ans=max(ans,guass(pri[i]));
    printf("%d\n", ans);
    return 0;
}


你可能感兴趣的:(2016CampDay7problemA.ABBA)