Matrix Power Series
poj 3233
题目大意
给你一个矩阵A,让你求S=A+A2+A3+…+AkS = A + A^2 + A^3 + … + A^kS=A+A2+A3+…+Ak
输入样例
2 2 4
0 1
1 1
输出样例
1 2
2 3
n⩽30,k⩽109,m<104,a∈A,a⩽32768n \leqslant 30,k \leqslant 10^9,m < 10^4,a\in A,a \leqslant32768n⩽30,k⩽109,m<104,a∈A,a⩽32768
解题思路
如果直接计算k遍会超时
看到矩阵我们考率矩阵乘法(doge)
我们设矩阵[Ai−1Si−2]\begin{bmatrix}A^{i-1} & S_{i - 2}\end{bmatrix}[Ai−1Si−2](A,S均为n∗nn*nn∗n的矩阵,Si=A+A1+A2…+AiS_i=A+A^1+A^2…+A^iSi=A+A1+A2…+Ai)
那么有[Aisi−1]=[Ai−1si−2]×[A101]\begin{bmatrix}A^i & s_{i-1}\end{bmatrix}=\begin{bmatrix}A^{i-1} & s_{i-2}\end{bmatrix} \times \begin{bmatrix}A & 1\\ 0 & 1\end{bmatrix}[Aisi−1]=[Ai−1si−2]×[A011]
注:1为单位矩阵
这样就可以快速幂了
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define wyc mod
ll n, k, mod;
struct matrix
{ll n, m, a[100][100];matrix operator *(const matrix &b) const//矩阵乘法{matrix c;c.n = n;c.m = b.m;for (ll i = 1; i <= c.n; ++i)for (ll j = 1; j <= c.m; ++j)c.a[i][j] = 0;for (ll i = 1; i <= n; ++i)for (ll k = 1; k <= m; ++k)for (ll j = 1; j <= c.m; ++j)c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j] % wyc) % wyc;return c;}
}A, B;
void Counting(ll g)//快速幂
{while(g){if (g & 1) A = A * B;B = B * B;g >>= 1; }
}
int main()
{scanf("%lld%lld%lld", &n, &k, &mod);A.n = n;A.m = n * 2;B.n = n * 2;B.m = n * 2; for (ll i = 1; i <= n; ++i)for (ll j = 1; j <= n; ++j){scanf("%lld", &A.a[i][j]);B.a[i][j] = A.a[i][j];}for (ll i = 1; i <= n; ++i)B.a[i][i + n] = B.a[i + n][i + n] = 1;//建初始矩阵Counting(k);for (ll i = 1; i <= n; ++i){for (ll j = 1; j <= n; ++j)printf("%lld ", A.a[i][j + n] % wyc);putchar(10);}return 0;
}