POJ 3233 Matrix Power Series (矩阵乘法,分块矩阵)

时间限制: 1 Sec  内存限制: 128 MB
提交: 27  解决: 6
[提交] [状态] [命题人:admin]

题目描述

Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

输入

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 the elements of S modulo m in the same way as A is given.

样例输入

2 2 4
0 1
1 1

样例输出

1 2
2 3

 

构造一个$2n*2n$的矩阵。

$
left{
egin{matrix}
A & one  \
zero & one 
end{matrix}
ight}
$ ,其中one为单位矩阵,zero为0矩阵, $
left{
egin{matrix}
A & one  \
zero & one 
end{matrix}
ight}^{k+1} = left{
egin{matrix}
A^{k+1} & A^k+A^{k-1}+...+A+one  \
zero & one 
end{matrix}
ight}
$ ,取右上角的矩阵然后减去一个单位矩阵就是所求结果

#include "bits/stdc++.h"

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
int mod;

struct martix {
    ll a[100][100];
};


martix mul(martix a, martix b) {
    martix ret;
    for (int i = 1; i <= 2 * n; i++) {
        for (int j = 1; j <= 2 * n; j++) {
            ret.a[i][j] = 0;
            for (int k = 1; k <= 2 * n; k++) {
                ret.a[i][j] = (ret.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
            }
        }
    }
    return ret;
}


martix powmod(martix a, int b) {
    martix ret;
    memset(ret.a, 0, sizeof(ret.a));
    for (int i = 0; i < 80; i++) ret.a[i][i] = 1;
    while (b) {
        if (b & 1)ret = mul(ret, a);
        a = mul(a, a);
        b >>= 1;
    }
    return ret;
}

int main() {
    //freopen("in.txt", "r", stdin);
    martix A, S;
    memset(A.a, 0, sizeof(A.a));
    int k;
    cin >> n >> k >> mod;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> A.a[i][j];
        }
        A.a[i][i + n] = 1;
        A.a[i + n][i + n] = 1;
    }

    S = powmod(A, k + 1);

    for (int i = 1; i <= n; i++) {
        int flag = 0;
        for (int j = 1; j <= n; j++) {
            if (i == j)S.a[i][j + n]--;
            if (flag) cout << " ";
            flag = 1;
            cout << (S.a[i][j + n] + mod) % mod;
        }
        cout << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/albert-biu/p/10736701.html