AcWing - 226 - 233 = Matrix Matrix quick power

https://www.acwing.com/problem/content/228/

To note a similar way, except this recursion formula can also be used to push fast power matrix, maybe even faster, after all, the number of combinations is no quick algorithm.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int mod = 10000007;
struct Matrix {
    static const int MAXN = 15;
    ll ma[MAXN][MAXN];
    Matrix() {
        init();
    }
    void init() {
        memset(ma, 0, sizeof(ma));
    }
    void setE() {
        init();
        for(int i = 0; i < MAXN; ++i)
            ma[i][i] = 1;
    }
    Matrix operator+(const Matrix &m)const {
        Matrix Tmp;
        Tmp.init();
        for(int i = 0; i < MAXN; ++i) {
            for(int j = 0; j < MAXN; ++j)
                Tmp.ma[i][j] += (ma[i][j] + m.ma[i][j]) % mod;
        }
        for(int i = 0; i < MAXN; ++i) {
            for(int j = 0; j < MAXN; ++j)
                if(Tmp.ma[i][j] >= mod)
                    Tmp.ma[i][j] %= mod;
        }
        return Tmp;
    }

    Matrix operator*(const Matrix &m)const {
        Matrix Tmp;
        Tmp.init();
        for(int k = 0; k < MAXN; ++k) {
            for(int i = 0; i < MAXN; ++i) {
                register int r = ma[i][k];
                for(int j = 0; j < MAXN; ++j)
                    Tmp.ma[i][j] += (r * m.ma[k][j]) % mod;
            }
        }
        for(int i = 0; i < MAXN; ++i) {
            for(int j = 0; j < MAXN; ++j)
                if(Tmp.ma[i][j] >= mod)
                    Tmp.ma[i][j] %= mod;
        }
        return Tmp;
    }
    void show(int n) {
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                printf("%2d ", ma[i][j]);
            }
            puts("");
        }
    }
};

Matrix qpow(Matrix x, ll n) {
    Matrix res;
    res.setE();
    while(n) {
        if(n & 1)
            res = res * x;
        x = x * x;
        n >>= 1;
    }
    return res;
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n, m;
    while(~scanf("%d%d", &n, &m)) {
        Matrix F;
        F.ma[0][0] = 3;
        F.ma[1][0] = 23;
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &F.ma[i + 1][0]);
        }
        int k = n + 2;
        Matrix A;
        A.ma[0][0] = 1;
        A.ma[1][0] = 1;
        A.ma[1][1] = 10;
        for(int i = 1; i <= n; ++i) {
            A.ma[i + 1][0] = 1;
            A.ma[i + 1][1] = 10;
            for(int j = 1; j <= i; ++j)
                A.ma[i + 1][j + 1] = 1;
        }
        //A.show(k);
        A = qpow(A, m);
        F = A * F;
        printf("%d\n", F.ma[n + 1][0]);
    }
}

Guess you like

Origin www.cnblogs.com/Inko/p/11543590.html