zoukankan      html  css  js  c++  java
  • 随手练——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;
    }
  • 相关阅读:
    在线古书式竖排工具
    智能实验室-全能优化(Guardio) 5.04.0.1040
    智能实验室-全能优化(Guardio) 5.03.0.1011
    在线专用链双向转换
    智能实验室-杀马(Defendio) 4.32.0.1020
    智能实验室-杀马(Defendio) 4.31.0.1010
    智能实验室-全能优化(Guardio) 4.999.0.981
    智能实验室-杀马(Defendio) 4.27.0.951
    智能实验室-全能优化(Guardio) 5.02.0.1000
    智能实验室-结构化存储浏览器(SSExplorer) 2.0.0.200
  • 原文地址:https://www.cnblogs.com/czc1999/p/10395619.html
Copyright © 2011-2022 走看看