Matrix Power Series
题意:
给定 n×n 的整数矩阵 A 和正整数 k和m, 令 S=A + A2 + A3 +…+ Ak , 求 S mod m 的值 .
数据范围:
n (n ≤ 30), k (k ≤ 109) , m (m < 104)
解题思路:
矩阵快速幂 + 等比数列二分求和
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=35;
struct mat {
int arr[N][N];
// mat()
// {
// memset(arr,0,sizeof(arr));//初始化!!!
// }
};
int n, k, m;
mat mul(mat a, mat b) {//矩阵乘法
mat ret;
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
ret.arr[i][j]=0;
for(int c=0; c<n; c++)
ret.arr[i][j]=(ret.arr[i][j]+a.arr[i][c]*b.arr[c][j]%m)%m;
}
}
return ret;
}
mat add(mat a, mat b) {
mat ret;
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
ret.arr[i][j]=(a.arr[i][j]+b.arr[i][j])%m;
}
}
return ret;
}
mat power(mat a, int k) {
mat b;
// for(int i=0; i<n; i++)
// b.arr[i][i]=1;//初始化为单位矩阵
//若没有前面struct里的初始化,则b的初始化如下
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
b.arr[i][j]=(i==j ? 1 : 0);
}
}
while(k) {//矩阵快速幂
if(k&1)
b=mul(a, b);//注意a,b的顺序
a=mul(a, a);
k>>=1;//别漏了"="
}
return b;
}
mat dic(mat a, int t) {//等比数列二分求和
if(t==1) return a;
if(t&1) //k为奇数时,将它化为偶数
return add(dic(a, t-1), power(a, t));
else
return mul(add(power(a, 0), power(a, t/2)), dic(a, t/2));
}
int main() {
mat init, res;
scanf("%d %d %d", &n, &k, &m);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
scanf("%d", &init.arr[i][j]);
}
}
res=dic(init, k);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
if(j) printf(" ");
printf("%d", res.arr[i][j]);
}
printf("\n");
}
return 0;
}