题意很好理解,矩阵幂乘取模
基本思路跟那个poj 1995 差不多,都要用到快速幂的思想。
唯一的区别就是整数乘法变成了矩阵乘法。
还有一个重要的地方就是
k = 6 有: S(6) = (1 + A^3) * (A + A^2 +A^3) = (1 + A^3) * S(3)。
#include<cstdio>
#include<iostream>
using namespace std;
const int Maxsize = 35;
typedef struct
{
int m[Maxsize][Maxsize];
} Matrax;
Matrax a,per;
int n,M;
void init_Matrax() /*矩阵的输入*/
{
for(int i = 0 ; i < n ; i ++)
{
for(int j = 0 ; j < n ; j++)
{
scanf("%d",&a.m[i][j]);
a.m[i][j]%=M;
per.m[i][j] = (i==j);
}
}
}
Matrax multi(Matrax a,Matrax b) /*矩阵乘法*/
{
Matrax c;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
c.m[i][j] = 0;
for(int 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 power(int k) /*矩阵快速幂*/
{
Matrax p,ans;
ans = per;
p = a;
while(k)
{
if(k&1)
{
ans = multi(ans,p);
}
k>>=1;
p = multi(p,p);
}
return ans;
}
Matrax add(Matrax a,Matrax b)/*矩阵加法*/
{
Matrax c;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
c.m[i][j] = (a.m[i][j] + b.m[i][j])%M;
}
}
return c;
}
Matrax sum(int k) /*求S,鉴于矩阵运算的复杂性,这里用到类似二分来求和,不然会超时的*/
{
if(k == 1)
{
return a;
}
Matrax temp,b;
temp = sum(k/2);
if(k&1)
{
b = power(k/2+1);
temp = add(temp,multi(temp,b));
temp = add(temp,b);
}
else
{
b = power(k/2);
temp = add(temp,multi(temp,b));
}
return temp;
}
int main()
{
int k;
Matrax ans;
cin>>n>>k>>M;
init_Matrax();
ans = sum(k);
int i ,j;
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;
}