#include"iostream"
#include"stdio.h"
#include"string.h"
using namespace std;
struct Mat{
int res[45][45];
Mat(){memset(res,0,sizeof(res));}
}I;
int n,m,k;
Mat mut(Mat a,Mat b) //矩阵乘法
{
Mat c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
c.res[i][j]+=a.res[i][k]*b.res[k][j];
c.res[i][j]%=m;
}
return c;
}
Mat add(Mat a,Mat b) //矩阵加减
{
Mat c;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
c.res[i][j]=a.res[i][j]+b.res[i][j];
c.res[i][j]%=m;
}
}
return c;
}
Mat pow(Mat a,int cnt)
{
Mat E=I,p=a;
while(cnt)
{
if(cnt%2)
{
E=mut(E,p); //任何矩阵 矩阵都是保持不变的
cnt--;
}
cnt/=2;
p=mut(p,p);
}
return E;
}
Mat sum(Mat a,int cnt) //等比数列二分求和
{
if(cnt==1) return a;
Mat t=sum(a,cnt/2);
if(cnt%2)
{
Mat cur=pow(a,cnt/2+1);
t=add(t,mut(t,cur));
t=add(cur,t);
}
else
{
Mat cur=pow(a,cnt/2);
t=add(t,mut(t,cur));
}
return t;
}
void print(Mat a)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<a.res[i][j]<<" ";
cout<<endl;
}
}
int main()
{
while(cin>>n>>k>>m)
{
Mat a;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&a.res[i][j]);
a.res[i][j]%=m; //一定要有
if(i==j) I.res[i][j]=1;else I.res[i][j]=0;
}
Mat ans=sum(a,k);
print(ans);
}
}
POJ 3233 矩阵运算,等比数列二分求和,矩阵
最新推荐文章于 2021-03-25 00:47:30 发布