I-Matrix Power Series POJ - 3233 矩阵快速幂+分治
Problem 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
题解
将原式拆分为 S = (1 + Ak/2)* Sk/2 (+ Ak)然后递归
相当于把 A A2 A3 … 分别计算的复杂度省去,只算一个 AK即可
递归也是logn
复杂度
O(n3 * logk)== 303030*32 == 1e5 ~ 1e6
算法
二分
分治
代码
#include<bits\stdc++.h>
using namespace std;
int n, k, mod;
typedef struct node {
int e[32][32];
void Init(){
memset(e, 0, sizeof(e));
for(int i = 0; i < 32; i++)
e[i][i] = 1;
}
}Mat;
Mat ans, mp;
Mat Add(Mat a, Mat b) {
Mat c;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
c.e[i][j] = a.e[i][j] + b.e[i][j];
return c;
}
Mat Mut(Mat a, Mat b) {
Mat c;
memset(c.e, 0, sizeof(c.e));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
c.e[i][j] += a.e[i][k] * b.e[k][j];
return c;
}
Mat quick_mod(Mat a, int power) {
Mat one;
one.Init();
while(power) {
if(power&1) one = Mut(one, a);
a = Mut(a,a);
power>>=1;
}
return one;
}
Mat get_sum(Mat a, int kk) {
if(kk == 1) return a;
Mat one; // 定义一个单位矩阵
one.Init();
one = Add(one, quick_mod(a, kk>>1));
one = Mut(one, get_sum(a, kk>>1));
if(kk&1) one = Add(one, quick_mod(a, kk));
return one;
}
int main() {
freopen("test.in", "r", stdin);
while(scanf("%d%d%d", &n, &k, &mod) == 3){
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d", &mp.e[i][j]);
ans = get_sum(mp, k);
for(int i = 0; i < n; i++){
for(int j = 0; j < n-1; j++){
printf("%d ", ans.e[i][j]);
}
printf("%d\n", ans.e[i][n-1]);
}
}
return 0;
}