题意:给定一个n*n的矩阵和一个整数k,计算 S = A +A^2 +A^3 + .....+ A^k
思路:不能暴力,会超时的所以我们要想一个办法化简,对于原式可以提取公因式
S = A +A^2 +A^3 + .....+ A^k/2 + A^k/2 * (A +A^2 +A^3 + .....+ A^k/2)
这样我们就可以只算A到A^k/2,同理这之间也可以用刚才的方法不停地二分知道只剩1个
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
struct Matrix
{
int row[32][32];
};
Matrix unit;
int n,k,m;
Matrix Matrix_add(Matrix a,Matrix b)
{
Matrix c;
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{
c.row[i][j]=a.row[i][j]+b.row[i][j];
c.row[i][j]%=m;
}
return c;
}
Matrix Matrix_Mul(Matrix a,Matrix b)
{
Matrix c;
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{
c.row[i][j]=0;
for (k=0; k<n; k++)
c.row[i][j]+=a.row[i][k]*b.row[k][j];
c.row[i][j]%=m;
}
return c;
}
Matrix Matrix_mod(Matrix a,int k)
{
Matrix sum = unit;
Matrix A = a;
while(k)
{
if(k&1)
{
k--;
sum = Matrix_Mul(sum,A);
}
else
{
A = Matrix_Mul(A,A);
k = k >> 1;
}
}
return sum;
}
Matrix Matrix_sum(Matrix a,int k)
{
if(k == 1)
return a;
else
{
Matrix sum,b,temp;
sum = Matrix_sum(a,k/2);
if(k % 2 == 1)
{
b = Matrix_mod(a,k/2+1);
sum = Matrix_add(sum,Matrix_Mul(b,sum));
sum = Matrix_add(sum,b);
}
else
{
b = Matrix_mod(a,k/2);
sum = Matrix_add(sum,Matrix_Mul(b,sum));
}
return sum;
}
}
int main()
{
while(scanf("%d%d%d",&n,&k,&m) != EOF)
{
Matrix a;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d",&a.row[i][j]);
a.row[i][j] = a.row[i][j] % m;//事先处理一下不处理时间会慢很多了
unit.row[i][j] = (i == j);
}
}
Matrix sum = Matrix_sum(a,k);
for(int i = 0; i < n; i++)
{
printf("%d",sum.row[i][0]);
for(int j = 1; j < n; j++)
{
printf(" %d",sum.row[i][j]%m);
}
printf("\n");
}
}
return 0;
}