Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 19189 | Accepted: 8099 |
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题目大意:
给定一个 n*n 的矩阵和一个整数 k,,要求的是S = A + A2 + A3 + … + Ak.
出的是 S%Mod
解题思路:
首先这是一个矩阵的快速幂,将Ak 用矩阵的快速幂求解出来(可以套模板),
可以推出以下结论
Sk = A + A2 + A3 + … + Ak
=(1+Ak/2)*(A + A2 + A3 + … + Ak/2 )+(Ak )
=(1+Ak/2)*(Sk/2 )+(Ak )
然后可以递归啦,首先计算的是 (1+ Ak/2 ),这里的 1 不仅是 1 它是一个单位矩阵,然后递归一下,最后判断一下奇偶性
要是偶数的时候就不用+(Ak ),要是奇数的话就+(Ak ),具体详见代码:
#include <iostream>
#include <cstring>
using namespace std;
typedef struct Mar
{
int m[40][40];
void Init()///初始化为单位矩阵
{
memset(m, 0, sizeof(m));
for(int i=0; i<40; i++)
m[i][i] = 1;
}
} Martrix;
int n, Mod;
Martrix Add(Martrix a, Martrix b)///矩阵加法
{
Martrix 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]) % Mod;///一定要模 Mod
return c;
}
Martrix Multi(Martrix a, Martrix b)///矩阵乘法
{
Martrix 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])%Mod;///一定要模 Mod,将数值减小
c.m[i][j] %= Mod;
}
}
return c;
}
Martrix quick_mod(Martrix a, int b)///矩阵的快速幂
{
Martrix ans;
ans.Init();
while(b)
{
if(b & 1)
ans = Multi(ans, a);
b>>=1;///二分
a = Multi(a, a);
}
return ans;
}
Martrix Get_sum(Martrix a, int k)///递归
{
if(k == 1)
return a;
Martrix ans;
ans.Init();
ans = Add(ans, quick_mod(a, k>>1));///1+A^(k/2)
ans = Multi(ans,Get_sum(a,k>>1));///剩下的
if(k & 1)///判断奇偶性
ans = Add(ans,quick_mod(a,k));
return ans;
}
int main()
{
int k;
while(cin>>n>>k>>Mod)
{
Martrix a;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
cin>>a.m[i][j];
Martrix ans = Get_sum(a,k);
for(int i=0; i<n; i++)
{
for(int j=0; j<n-1; j++)
cout<<ans.m[i][j]<<" ";
cout<<ans.m[i][n-1]<<endl;
}
}
return 0;
}