• 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;
    }


  • 相关阅读:
    软件开发过程中应当遵守的原则
    企业架构是什么?
    软件工程的精髓
    PHP获取自然周列表,周开始结束日期,月开始结束时间方法类
    JS替换textarea里的回车换行
    PHP连接PGSQL
    PT与PX的区别
    JQuery 翻页小记
    PHP中替换textarea时的回车换行
    HTML5 CanvasOreilly.Canvas.Pocket.Reference (4)
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046779.html
Copyright © 2020-2023  润新知