HDU1757 A Simple Math Problem(矩阵快速幂)

题目链接

题意:

x < 10时 f(x) = x. x >= 10时 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10) 并且ai(0<=i<=9) 只能是0或1. 求f(n)%m。 一张图一目了然。

#include<cstring>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const double pi = acos(-1);

int MOD;
const int maxn = 10;

struct Matrix{
    int mat[maxn][maxn];
};

//矩阵乘法
Matrix matrixmul(Matrix a,Matrix b){
    Matrix ret;
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j < maxn; j++){
            ret.mat[i][j] = 0;
            for(int k = 0; k < maxn; k++){
                ret.mat[i][j] += (a.mat[i][k]*b.mat[k][j])%MOD;
                ret.mat[i][j] %= MOD;
            }
        }
    return ret;
}

// a^n%MOD
Matrix M_quickpow(Matrix a, long long n){
    Matrix ret;
    memset(ret.mat, 0, sizeof(ret.mat));
    //构造单位矩阵
    for(int i = 0; i < maxn; i++)
        ret.mat[i][i] = 1;
    while (n){
        if (n & 1) ret = matrixmul(ret, a);
        n >>= 1;
        a = matrixmul(a, a);
    }
    return ret;
}



int main(){
    //freopen("a.txt", "r", stdin);
    int k, m;
    Matrix q;
    memset(q.mat, 0, sizeof(q.mat));
    while (~scanf("%d%d", &k, &MOD)){
        if(k<10) cout << k%MOD << endl;
        else{
            for(int i = 0; i < 10; i++)
                scanf("%d", &q.mat[0][i]);
            for(int i = 0; i < 9; i++){
                q.mat[i+1][i] = 1;
            }

            Matrix aa = M_quickpow(q, k-9);
            Matrix x;
            memset(x.mat, 0, sizeof(x.mat));
            for(int i = 0; i < 10; i++)
                x.mat[i][0] = 9-i;

            Matrix ans = matrixmul(aa, x);

            cout << ans.mat[0][0] << endl;
        }

    }
    return 0;
}

Zhao Li /
Published under (CC) BY-NC-SA in categories 算法  tagged with 快速幂  数学