zoukankan      html  css  js  c++  java
  • HDU 5015

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

    矩阵是表示状态转移的利器

    这题m很大,n非常小,所以开始的思考角度是能否从当前列推出下一列。有了这个角度,矩阵构造是很简单的

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    typedef __int64 LL;
    
    #define MOD 10000007
    
    #define Mat 15 //矩阵大小
      
    struct mat{//矩阵结构体,a表示内容,r行c列 矩阵从1开始  
        LL a[Mat][Mat];
        int r, c;  
        mat() {  
            r = c = 0;  
            memset(a, 0, sizeof(a));  
        }  
    };  
    
    void print(mat m) {  
        //printf("%d
    ", m.size);  
        for(int i = 0; i < m.r; i++) {  
            for(int j = 0; j < m.c; j++) printf("%d ", m.a[i][j]);  
            putchar('
    ');  
        }  
    }  
      
    mat mul(mat m1, mat m2, int mod) {  
        mat ans = mat();
        ans.r = m1.r, ans.c = m2.c;  
        for(int i = 1; i <= m1.r; i++)  
            for(int j = 1; j <= m2.r; j++)  
                if(m1.a[i][j])
                    for(int k = 1; k <= m2.c; k++)  
                        ans.a[i][k] = (ans.a[i][k] + m1.a[i][j] * m2.a[j][k]) % mod;  
        return ans;  
    }  
    
    mat quickmul(mat m, int n, int mod) {  
        mat ans = mat();  
        for(int i = 1; i <= m.r; i++) ans.a[i][i] = 1;  
        ans.r = m.r, ans.c = m.c;  
        while(n) {  
            if(n & 1) ans = mul(m, ans, mod);  
            m = mul(m, m, mod);  
            n >>= 1;  
        }  
        return ans;  
    }  
    
    /* 
    初始化ans矩阵 
    mat ans = mat(); 
    ans.r = R, ans.c = C;  
    ans = quickmul(ans, n, mod); 
    */
    
    int main() {
        int n, m;
        while(~scanf("%d%d", &n, &m)) {
            int a = n + 2;
            mat A = mat();
            A.r = 1, A.c = a;
            A.a[1][1] = 23, A.a[1][a] = 3;
            for(int i = 2; i <= n+1; i++)
                scanf("%d", &A.a[1][i]);
            mat M = mat();
            M.r = M.c = a;
            for(int i = 1; i < a; i++)
                M.a[1][i] = 10;
            for(int i = 1; i <= a; i++)
                M.a[a][i] = 1;
            for(int i = 2; i < a; i++) {
                for(int j = 2; j < a; j++) {
                    if(j >= i) M.a[i][j] = 1;
                }
            }
            printf("%d
    ", mul(A, quickmul(M, m, MOD), MOD).a[1][n+1]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    linux zip命令 tar命令 【压缩、解压缩】参数列表:
    理解 uptime 的:“平均负载”? 如何模拟测试
    mark_Linux_wc
    我应该怎么学习SAP?
    SAP 销售订单交货对成本中心记账
    从华为“鸿蒙”备胎看IT项目建设
    什么样的系统算是坑
    写在Logg SAP项目上线之际
    SAP系统邮件功能配置
    警惕SAP项目被“中间商赚差价”
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/4581177.html
Copyright © 2011-2022 走看看