POJ 3233 Matrix Power Series (构造矩阵 + 矩阵快速幂)

Matrix Power Series

Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 29036   Accepted: 11805

Description

Given a n × n matrix A and a positive integer k, find the sum S = A^1 + A^2 + A^3 + ... +A^k

Input

The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30)k (k ≤ 10^9) and m (m < 10^4). 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

题目不长,就是要你求S % m,S是一个矩阵。要算的东西跟矩阵有关,而且还有幂,所以首先想到矩阵快速幂,但如果直接暴力算,即把A^1, A^2,...,A^k用矩阵快速幂算出来,然后在加一起,显然会超时。所以不妨换个思路,我们尝试构造下面的矩阵

                                                                                          T = \begin{pmatrix} A & O\\ E & E \end{pmatrix}

其中A为题目所给的矩阵(n * n),O为n阶零矩阵,E为n阶单位阵。

然后尝试计算T^2,T^3, ..., T^n,T^{n+1}

T^2 = \begin{pmatrix} A & O\\ E & E \end{pmatrix} * \begin{pmatrix} A & O\\ E & E \end{pmatrix} = \begin{pmatrix} A^2 & O\\ A + E & E \end{pmatrix}

T^3 =T^2 * \begin{pmatrix} A & O\\ E & E \end{pmatrix} = \begin{pmatrix} A^2 & O\\ A + E & E \end{pmatrix} * \begin{pmatrix} A & O\\ E & E \end{pmatrix} = \begin{pmatrix} A^3 & O\\ A^2 + A + E & E \end{pmatrix}

....

T^n =T^{n-1} * \begin{pmatrix} A & O\\ E & E \end{pmatrix} = \begin{pmatrix} A^n & O\\ A^{n-1} + A^{n-2}+...+A + E & E \end{pmatrix}

T^{n+1} =\begin{pmatrix} A^{n+1} & O\\ A^{n} + A^{n-1}+...+A + E & E \end{pmatrix}

是不是发现,要求的矩阵S就是矩阵T^{n+1}的左下角的子矩阵然后在减去一个单位阵E

有了思路代码实现就很简单了

C++代码

#include <iostream>
#include <stdio.h>
#include <string.h>
#define N 64
using namespace std;
int n, m;
struct Matrix{
    int _[N][N];
    Matrix() {
        memset(_, 0, sizeof(_));
    }
};
//矩阵相乘
Matrix matrixMultiply(Matrix &A, Matrix &B) {
    Matrix C;
    for (int i = 0; i< 2*n; i++)
        for (int j = 0; j< 2*n; j++)
            for (int k = 0; k< 2*n; k++)
                C._[i][k] = (C._[i][k] % m + (A._[i][j] % m * B._[j][k] % m) % m) % m;
    return C;
}
//矩阵快速幂
Matrix matrixPower(Matrix &A, long long k) {
    Matrix E;
    for (int i = 0; i< 2*n; i++)
        E._[i][i] = 1;
    while (k != 0) {
        if (k % 2) E = matrixMultiply(E, A);
        A = matrixMultiply(A, A);
        k /= 2;
    }
    return E;
}

int main() {
    long long k;
    while (scanf("%d%lld%d", &n, &k, &m) == 3) {
        int A[32][32];
        for (int i = 0; i< n; i++)
            for (int j = 0; j< n; j++)
                scanf("%d", &A[i][j]);
        int E[32][32];
        memset(E, 0, sizeof(E));
        for (int i = 0; i< n; i++)
            E[i][i] = 1;
        Matrix S;
        for (int i = 0; i< n; i++)
            for (int j = 0; j< n; j++)
                S._[i][j] = A[i][j];
        for (int i = n; i< 2*n; i++)
            for (int j = 0; j< n; j++)
                S._[i][j] = E[i - n][j];
        for (int i = n; i< 2*n; i++)
            for (int j = n; j< 2*n; j++)
                S._[i][j] = E[i - n][j - n];
        S = matrixPower(S, k + 1);
        for (int i = n; i< 2*n; i++){
            for (int j = 0; j< n; j++){
                S._[i][j] - E[i - n][j] < 0 ? printf("%d ", m - 1) : printf("%d ",S._[i][j] - E[i - n][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/daydream13580130043/article/details/87262963
今日推荐