您的位置:首页 > 编程语言 > Lua

HDU 2827 The Evaluation of Determinant 题解

2017-06-06 16:43 369 查看

题意

给一个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: