hdu 5015 233矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5015

需要构造一个 n+2 维的矩阵。

就是要增加一维去维护2333这样的序列。

可以发现 2333 = 233*10 + 3

所以增加了一维就 是1, 然后就可以全部转移了。

 10 0 0 0 0 ... 1
                                                                                                  1 1 0 0 0  ..... 0
                                                                                                  0 1 1 0 ...       0
                                                                                                  . . .. . .. . .. .. .. . .
                                                                                                 0 0 0 0 0 ....    1,

矩阵乘法+快速幂优化递推。

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <bitset>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;
const int N = 15;
const int modo = 10000007;
int k,m;
struct Matrix{
    LL mat[N][N];
    void unit(){
        clr0(mat);
        for (int i=0;i<=k;++i) mat[i][i]=1;
    }
    Matrix operator*(Matrix b){
        Matrix c;
        memset(c.mat,0,sizeof(c.mat));
        for (int i=0;i<=k;++i)
            for (int l=0;l<=k;++l)
                if (mat[i][l])
                    for (int j=0;j<=k;++j)
                    c.mat[i][j] = (c.mat[i][j] + mat[i][l] * b.mat[l][j]) % modo;
        return c;
    }
};
Matrix operator^(Matrix a,int m){
    Matrix t;
    t.unit();
    while(m){
        if (m&1) t=t*a;
        a=a*a;
        m>>=1;
    }
    return t;
}
int b[15];
int main (){
    while(~RD2(k,m)){
        b[0] = 233;
        for(int i = 1;i <= k;++i)
            RD(b[i]);
        b[++k] = 3;
        Matrix c;
        c.unit();
        for(int i = 0;i < k;++i){
            for(int j = 0;j < i;++j){
                c.mat[i][j] = 1;
            }
        }
        c.mat[0][0] = 10,c.mat[0][k] = 1;
//        for(int i = 0;i <= k;++i){
//            for(int j = 0;j <= k;++j){
//                cout<<c.mat[i][j]<<' ';
//            }
//            cout<<endl;
//        }
        Matrix d = c^m;

        int ans = 0;
        for(int i = 0;i <= k;++i)
            ans = (ans + d.mat[k-1][i] * b[i])%modo;
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(HDU)