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
题目大意
对于任意给定的 r r r阶方阵 A A A,求 S [ n ] = A + A 2 + A 3 + … + A n S[n]=A+A^2+A^3+…+A^n S[n]=A+A2+A3+…+An
解题思路
构造一个1*2的矩阵
J 1 = [ A n − 1 S [ n − 2 ] ] J_1 = \begin{bmatrix} A^{n-1} & S[n-2] \end{bmatrix} J1=[An−1S[n−2]]
构造一个2*2的矩阵 J 2 J_2 J2
使得 J 1 = [ A n − 1 S [ n − 2 ] ] ∗ J 2 = [ A n S [ n − 1 ] ] J_1 = \begin{bmatrix} A^{n-1} & S[n-2] \end{bmatrix} * J_2 =\begin{bmatrix} A^n & S[n-1] \end{bmatrix} J1=[An−1S[n−2]]∗J2=[AnS[n−1]]
那么 J 2 = [ A E O E ] J_2=\begin{bmatrix} A & E\\ O &E \end{bmatrix} J2=[AOEE]
O:全零矩阵
E(单位矩阵):主对角线上是1(任何一个矩阵乘上单位矩阵都等于它本身)(随便列两个矩阵都可以验证的)
那么矩阵套矩阵怎么算呢,肯定不是矩阵乘法套矩阵乘法这么弱智啊~~(我就是那个弱智)~~
把矩阵拆开来,左上角是A,右上角和右下角是单位矩阵,左下角是全零矩阵,矩阵大小 ( n ∗ 2 ) ∗ ( n ∗ 2 ) (n*2)*(n*2) (n∗2)∗(n∗2)以
以 n = 3 n=3 n=3为例
[ A 1 , 1 A 1 , 2 A 1 , 3 1 0 0 A 2 , 1 A 2 , 2 A 2 , 3 0 1 0 A 3 , 1 A 3 , 2 A 3 , 3 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 ] \begin{bmatrix} A_{1,1} & A_{1,2} & A_{1,3} & 1 & 0&0 \\ A_{2,1} & A_{2,2} & A_{2,3} & 0 & 1 &0 \\ A_{3,1} & A_{3,2} & A_{3,3} & 0 & 0 &1 \\ 0 & 0 & 0 & 1 & 0&0 \\ 0 & 0 & 0 & 0 & 1& 0\\ 0 &0 & 0 & 0 & 0 &1 \end{bmatrix} ⎣⎢⎢⎢⎢⎢⎢⎡A1,1A2,1A3,1000A1,2A2,2A3,2000A1,3A2,3A3,3000100100010010001001⎦⎥⎥⎥⎥⎥⎥⎤
Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
struct DT{
ll n, m;
ll aed[70][70];
}A, B, Bc;
ll n, Mod, k;
DT operator * (DT a, DT b){
DT c;
memset (c.aed, 0, sizeof (c.aed));
c.n = a.n, c.m = b.m;
for (int k = 1; k <= a.m; k++)
for (int i = 1; i <= c.n; i++)
for (int j = 1; j <= c.m; j++)
c.aed[i][j] = (c.aed[i][j] + a.aed[i][k] * b.aed[k][j] % Mod) % Mod;
return c;
}
void power (ll x){
if (x == 1)
{
B = Bc;
return;
}
power (x / 2);
B = B * B;
if (x % 2)
B = B * Bc;
}
int main(){
scanf ("%lld%lld%lld", &n, &k, &Mod);
A.n = A.m = Bc.m = Bc.n = n * 2;
//A = A 和 J1;J2 = Bc和B
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
scanf ("%lld", &A.aed[i][j]);
Bc.aed[i][j] = A.aed[i][j];//J2的左上角是A数组
}
for (int i = 1; i <= n; i++)
Bc.aed[i][i + n] = Bc.aed[i + n][i + n] = 1;//J2的右上角和右下角是单位矩阵
power (k);
A = A * B;
for (int i = 1; i <= n; i++)
{
for (int j = n + 1; j <= n * 2; j++)
printf ("%lld ", A.aed[i][j]);
printf ("\n");
}
}