• [HDOJ2604]Queuing(递推,矩阵快速幂)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604

    递推式是百度的,主要是练习一下如何使用矩阵快速幂优化。

    递推式:f(n)=f(n-1)+f(n-3)+f(n-4),其中f(0)=2, f(1)=4, f(2)=6, f(3)=9。

    当n>4时候,需要通过这个关系来递推。

    构造矩阵这种东西我以前一直认为是很玄学的,但是如果深入研究的话不难发现其实也有规律可循。这是一个齐次递推式,很好构造。

    我们希望通过如下矩阵(1)得到矩阵(2)

    | f(n) |      |f(n+1)|
    |f(n-1)|      | f(n) |
    |f(n-2)|      |f(n-1)|
    |f(n-3)|      |f(n-2)|
      (1)            (2) 

    那么实际上,我们是通过一个转换矩阵把f(n),f(n-1),f(n-2)移动了一下位置,并且推出了f(n+1)。再考虑到矩阵乘法的特性,我们就能得到一个递推矩阵:

    |1 0 1 1|
    |1 0 0 0|
    |0 1 0 0|
    |0 0 1 0|

    我把第一行列为递推方程的系数,这样递推矩阵的第一列和目标矩阵的整列相乘即可得到递推的下一个结果。那剩下的怎么办呢?向下看会发现,按照行x列的特性,分别又列到了对应的位置。再根据矩阵乘法的性质就会很容易证明满足递推方程。

    代码如下:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <fstream>
     8 #include <cassert>
     9 #include <cstdio>
    10 #include <bitset>
    11 #include <vector>
    12 #include <deque>
    13 #include <queue>
    14 #include <stack>
    15 #include <ctime>
    16 #include <set>
    17 #include <map>
    18 #include <cmath>
    19 
    20 using namespace std;
    21 
    22 const int maxn = 10;
    23 typedef struct Matrix {
    24     int m[maxn][maxn];
    25     int r;
    26     int c;
    27     Matrix(){
    28         r = c = 0;
    29         memset(m, 0, sizeof(m));
    30     } 
    31 } Matrix;
    32 
    33 Matrix mul(Matrix m1, Matrix m2, int mod) {
    34     Matrix ans = Matrix();
    35     ans.r = m1.r;
    36     ans.c = m2.c;
    37     for(int i = 1; i <= m1.r; i++) {
    38         for(int j = 1; j <= m2.r; j++) {
    39                for(int k = 1; k <= m2.c; k++) {
    40                 if(m2.m[j][k] == 0) continue;
    41                 ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
    42             }
    43         }
    44     }
    45     return ans;
    46 }
    47 
    48 Matrix quickmul(Matrix m, int n, int mod) {
    49     Matrix ans = Matrix();
    50     for(int i = 1; i <= m.r; i++) {
    51         ans.m[i][i]  = 1;
    52     }
    53     ans.r = m.r;
    54     ans.c = m.c;
    55     while(n) {
    56         if(n & 1) {
    57             ans = mul(m, ans, mod);
    58         }
    59         m = mul(m, m, mod);
    60         n >>= 1;
    61     }
    62     return ans;
    63 }
    64 
    65 int n, m;
    66 
    67 int main() {
    68     // freopen("in", "r", stdin);
    69     while(~scanf("%d %d", &n, &m)) {
    70         Matrix p;
    71         p.r = 4, p.c = 1;
    72         p.m[1][1] = 9;
    73         p.m[2][1] = 6;
    74         p.m[3][1] = 4;
    75         p.m[4][1] = 2;
    76         if(n <= 4) {
    77             printf("%d
    ", p.m[4-n+1][1] % m);
    78             continue;
    79         }
    80         Matrix s;
    81         s.r = s.c = 4;
    82         s.m[1][1] = 1; s.m[1][2] = 0, s.m[1][3] = 1, s.m[1][4] = 1;
    83         s.m[2][1] = 1; s.m[2][2] = 0, s.m[2][3] = 0, s.m[2][4] = 0;
    84         s.m[3][1] = 0; s.m[3][2] = 1, s.m[3][3] = 0, s.m[3][4] = 0;
    85         s.m[4][1] = 0; s.m[4][2] = 0, s.m[4][3] = 1, s.m[4][4] = 0;
    86         s = quickmul(s, n-4, m);
    87         int ans = 0;
    88         for(int i = 1; i <= p.r; i++) {
    89             ans = (ans + (p.m[i][1] * s.m[1][i]) % m) % m;
    90         }
    91         printf("%d
    ", ans % m);
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    【Angular2】ng2的开始_组件
    【js框架】随笔
    【sublime text3】个性化定制
    PLSQL中文乱码问题
    Microsoft office 2010密钥
    node_oracle连接
    oracle安装配置
    Logging in Java
    Java 基础
    Hibernate
  • 原文地址:https://www.cnblogs.com/kirai/p/5413884.html
Copyright © 2020-2023  润新知