随手练——HDU 5015 矩阵快速幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5015

  看到这个限时,我就知道这题不简单~~矩阵快速幂,找递推关系

 

我们假设第一列为:

23

a1

a2

a3

a4

则第二列为:

23*10+3

23*10+3+a1

23*10+3+a1+a2

23*10+3+a1+a2+a3

23*10+3+a1+a2+a3+a4

进一步转化可以得到:

代码:

#include <iostream>
#include <string.h>
using namespace std;
#define N 15
#define mod 10000007

typedef long long LL;

int n;
class Matrix{
public:
    LL mat[N][N];
    Matrix() {
        for (int i = 0; i < N; i++) {
            memset(mat[i], 0, sizeof(mat[i]));
        }
    }
    Matrix operator*(Matrix b){
        Matrix temp;
        for (int i = 0; i <= n + 1; i++){
            for (int j = 0; j <= n + 1; j++){
                for (int k = 0; k <= n + 1; k++){
                    if (mat[i][k] && b.mat[k][j]){
                        temp.mat[i][j] = (temp.mat[i][j] + (mat[i][k] % mod * b.mat[k][j] % mod) % mod) % mod;
                    }
                }
            }
        }
        return temp;
    }
};

void MatrixMulti(Matrix &M,int m){
    Matrix ans;    
    for (int i = 0; i <= n + 1; i++)
        ans.mat[i][i] = 1;
    while (m){
        if (m & 1)
            ans = ans * M;
        m >>= 1;
        M = M * M;
    }
    M = ans;
}
Matrix initialize(){
    Matrix M;
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= n + 1; j++) {
            if (j == 0)M.mat[i][j] = 10;
            else if (i >= j)M.mat[i][j] = 1;
            else if (j == n + 1)M.mat[i][j] = 1;
            else M.mat[i][j] = 0;
        }
    }
    M.mat[n + 1][n + 1] = 1;
    return M;
}
int main(){
    int i, m;
    while (~scanf("%d%d", &n, &m)){
        int a[N];a[0] = 23;a[n + 1] = 3;
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        Matrix M = initialize();
        MatrixMulti(M, m);
        LL res = 0;
        for (i = 0; i <= n + 1; i++)
            res = (res + (M.mat[n][i] % mod * a[i] % mod) % mod) % mod;
        cout << res << endl;
    }
    return 0;
}

 

本来是不想直接 mat[N] [N]这样直接开个大数组,时间空间上都浪费,但是这题用指针写起来真的很麻烦!!!而且不知道哪儿写错了,好一会儿我也找不到 -_-,就换成上面这个了。

#include <iostream>
#include <stdio.h>
using namespace std;

typedef long long ll;
#define mod 10000007

int** initialize(int *A,int n) {
    A[0] = 23;
    for (int i = 1; i <= n; i++) {
        cin >> A[i];
    }
    A[n + 1] = 3;
    int **M = new int*[n + 2];
    for (int i = 0; i <= n + 1; i++) {
        M[i] = new int[n + 2];
        for (int j = 0; j <= n + 1; j++) {
                if (j == 0)
                    M[i][j] = 10;
                else if (j <= i)M[i][j] = 1;
                else if (j == n + 1)M[i][j] = 1;
                else M[i][j] = 0;
        }
    }
    for (int i = 0; i <= n + 1; i++) {
        if (i == n + 1)M[n + 1][i] = 1;
        else M[n + 1][i] = 0;
    }
    return M;
}
void MatrixMulti(int **M1,int **M2,int n,int **M) {
    int t[10][10] = { 0 };
    for (int i = 0; i <= n + 1; i++) {
        for (int j = 0; j <= n + 1; j++) {
            for (int k = 0; k <= n + 1; k++) {
                t[i][j] = (t[i][j] + M1[i][k] % mod * M2[k][j] % mod) % mod;
            }
        }
    }
    for (int i = 0; i <= n + 1; i++) {
        for (int j = 0; j <= n + 1; j++) {
            M[i][j] = t[i][j];
        }
    }

}
int **getBasicMatrix(int n) {
    int **m = new int*[n + 2];
    for (int i = 0; i <= n + 1; i++) {
        m[i] = new int[n + 2];
        for (int j = 0; j <= n + 1; j++) {
            if (i == j)m[i][j] = 1;
            else m[i][j] = 0;
        }
    }
    return m;
}
int** MatrixQuickPower(int **M, int n, int m) {
    int **res = getBasicMatrix(n);
    while (m) {
        if (m & 1)
            MatrixMulti(res, M, n, res);
        MatrixMulti(M, M, n, M);
        m >>= 1;
    }
    return res;
}
int main() {
    int n, m;
    while (~scanf("%d%d", &n, &m)) {
        int res = 0; 
        int *A = new int[n + 2];
        int **M = initialize(A, n);
        M = MatrixQuickPower(M, n, m);
        for (int i = 0; i <= n + 1; i++) {
            res = (res + M[n][i] % mod * A[i] % mod) % mod;
        }
        cout << res << endl;
    }
    return 0;
}

 

posted @ 2019-02-18 17:04  czc1999  阅读(71)  评论(0编辑  收藏  举报