矩阵的快速幂模m
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 110;
struct Matrax
{
int m[MAXN][MAXN];
};
Matrax a, per;
int n, m;
void Inite()
{
int i, j;
for(i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
cin>>a.m[i][j];
a.m[i][j] %= m;
per.m[i][j] = (i == j);//表示单位阵,对角元素为1,其余元素为零
}
}
}
Matrax Add_Matrax(Matrax a, Matrax b)//两矩阵求和
{
Matrax c;
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
c.m[i][j] = (a.m[i][j] + b.m[i][j]) % m;
}
}
return c;
}
Matrax Multi_Matrax(Matrax a, Matrax b)//两矩阵相乘
{
Matrax c;
int i, j, k;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
c.m[i][j] = 0;
for (k = 0; k < n; ++k)
{
c.m[i][j] += a.m[i][k] * b.m[k][j];
}
c.m[i][j] %= m;
}
}
return c;
}
Matrax Quick_Power( int k )//矩阵快速幂模m的求法
{
Matrax p, ans = per;//per.m[i][j],表示的是单位矩阵
p = a;//a是最小单位,也是初始矩阵
while (k)
{
if(k & 1)
{
ans = Multi_Matrax(ans, p);
k--;
}
else
{
k /= 2;
p = Multi_Matrax(p, p);
}
}
return ans;
}
Matrax Sum_Matrax( int k )//利用二分求解,要不然会超时
{
if(k == 1)
return a;
int i, j;
Matrax temp, b;
temp = Sum_Matrax( k/2 );//求出矩阵多项式前一半的和
if(k & 1)//k为奇数
{
b = Quick_Power( k/2 + 1 );//中间项
temp = Add_Matrax(temp, Multi_Matrax(temp, b));//矩阵多项式后一半的和恰是前一半的和乘以中间项
temp = Add_Matrax(temp, b);//再加上中间项,其结果就是最终求得的多项式和
}
else
{
b = Quick_Power( k/2 );
temp = Add_Matrax(temp, Multi_Matrax(temp, b));
}
return temp;
}
int main()
{
int i, j, k;
while (~scanf("%d %d %d", &n, &k, &m))
{
Inite();
Matrax ans = Sum_Matrax(k);
for (i = 0; i < n; ++i)
{
for(j = 0; j < n-1; ++j)
{
cout<<ans.m[i][j]<<" ";
}
cout<<ans.m[i][j]<<endl;
}
}
return 0;
}