HDU 2827 The Evaluation of Determinant 题解

来源:互联网 发布:番茄工作法 软件 编辑:程序博客网 时间:2024/06/04 23:31

题意

给一个n阶行列式,求行列式的值对m取余的值

思路

高斯消元,但是这个行列式的值不一定与m互质,所以如果用互质的逆元求法快速幂来做会有问题,可以将m分解质因数,然后分别求行列式模这些质因数的值,再使用中国剩余定理合成回来

代码

#include <cstdio>#include <cmath>#include <cstdlib>#include <iostream>#include <vector>using std::vector;long long D[101][101],E[101][101];long long n,m,ans,dv;long long gcd(long long x,long long y){    if(x%y==0)        return y;    if(y%x==0)        return x;    if(x>y)        return gcd(y,x%y);    else return gcd(x,y%x);}void Gauss(){    long long t,temp,g,t1,t2,p,q;    for(long long i=0,j=0;i<n&&j<n;i++,j++)    {        t=i;        for(long long k=i;k<n;k++)            if(D[k][j]!=0)            {                t=k;                break;            }        if(D[t][j]==0)        {            i--;            continue;        }        if(t!=i)        {            ans=-ans;            for(long long k=0;k<n;k++)            {                temp=D[i][k];                D[i][k]=D[t][k];                D[t][k]=temp;            }        }        for(long long k=i+1;k<n;k++)            if(D[k][j]!=0)            {                if(D[i][j]>=0)                    p=D[i][j];                else p=-D[i][j];                if(D[k][j]>=0)                    q=D[k][j];                else q=-D[k][j];                g=gcd(p,q);                t1=D[k][j]/g;                t2=D[i][j]/g;                if(t2<0)                {                    t1=-t1;                    t2=-t2;                }                t1=(t1%m+m)%m;                t2=(t2%m+m)%m;                dv=(dv*(t2%m))%m;                for(long long l=0;l<n;l++)                    D[k][l]=(((D[k][l]*(t2%m))%m)-((D[i][l]*(t1%m))%m)+m)%m;            }        /*std::cout<<i<<" "<<j<<"m: "<<m<<std::endl;        for(long long ii=0;ii<n;ii++)        {            for(long long jj=0;jj<n;jj++)                std::cout<<D[ii][jj]<<" ";            std::cout<<std::endl;        }*/    }    return;}long long power(long long x,long long y,long long mo){    long long ret=1;    while(y>0)    {        if(y%2)            ret=(ret*x)%mo;        x=(x*x)%mo;        y/=2;    }    return ret;}vector<long long> mm;vector<long long> re;long long mq;long long chinaremain(){    long long ret=0,cr=1,temp;    for(long long i=0;i<mm.size();i++)    {        temp=re[i];        temp=(temp*power(mq/mm[i],mm[i]-2,mq))%mq;        temp=(temp*(mq/mm[i]))%mq;        ret=(ret+temp)%mq;    }    return ret;}int main(){    long long e,anss;    while(std::cin>>n>>m)    {        for(long long i=0;i<n;i++)            for(long long j=0;j<n;j++)                std::cin>>D[i][j];        for(long long i=0;i<n;i++)            for(long long j=0;j<n;j++)                E[i][j]=D[i][j];        e=sqrt(m);        mq=m;        for(long long i=2;i<=e;i++)            if(m%i==0)            {                mm.push_back(i);                while(m%i==0)                    m/=i;            }        if(m!=1)            mm.push_back(m);        anss=1;        for(long long i=0;i<mm.size();i++)        {            ans=1;            dv=1;            m=mm[i];            for(long long j=0;j<n;j++)                for(long long k=0;k<n;k++)                    D[j][k]=E[j][k];            for(long long j=0;j<n;j++)                for(long long k=0;k<n;k++)                    if(D[j][k]<0)                        D[j][k]=(D[j][k]-m*(D[j][k]/m)+m)%m;                    else if(D[j][k]>=m)                        D[j][k]%=m;            Gauss();            for(long long j=0;j<n;j++)                ans=(ans*D[j][j])%m;            re.push_back((ans*power(dv,m-2,m)%m+m)%m);        }        std::cout<<chinaremain()<<std::endl;        mm.clear();        re.clear();    }    return 0;}