Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 12008 | Accepted: 5131 |
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4 0 1 1 1
Sample Output
1 2 2 3
题意:给出矩阵A,求S = A + A2 + A3 + … + Ak
分析:把问题转化以加速,令
B = A I (这里的1是单位矩阵)
0 I
则B^(k + 1) = A^(k + 1) I + A + A2 + A3 + … + Ak
0 I
可以先用矩阵快速幂求B^(k + 1),再求出S
AC代码:
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef struct node
{
int m[65][65];
void init()
{
memset(m,0,sizeof(m));
}
}matrix;
matrix ans,b;
int n,k,m;
void init()
{
ans.init();
b.init();
scanf("%d%d%d",&n,&k,&m);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&b.m[i][j]);
b.m[i][j]%=m;
}
for(int i=0;i<n;i++)
{
b.m[i][n+i]=b.m[n+i][n+i]=1; //在矩阵b中添加单位矩阵
ans.m[i][i]=ans.m[n+i][n+i]=1; //初始化ans为单位矩阵
}
}
matrix mul(matrix a,matrix b)
{
matrix temp;
temp.init();
for(int i=0;i<n*2;i++)
for(int j=0;j<n*2;j++)
{
for(int k=0;k<n*2;k++)
temp.m[i][j]+=(a.m[i][k]*b.m[k][j])%m;
temp.m[i][j]%=m;
}
return temp;
}
void solve()
{
k++;
while(k)
{
if(k&1)
ans=mul(ans,b);
b=mul(b,b);
k>>=1;
}
}
void Output() //输出时要减单位矩阵
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i!=j) printf("%d ",ans.m[i][j+n]);
else printf("%d ",ans.m[i][j+n]-1);
}
printf("\n");
}
}
int main()
{
init();
solve();
Output();
return 0;
}