• HDU1757


    解题思路:分析需要不少时间,比较懒,直接把别人的分析贴在这里,

      然后贴上自己写的代码:

    K相当之大。所以逐一递推的算法无法胜任。这时我们就不得不运用矩阵加速。首先来讲一下矩阵乘法:
    若一矩阵的列数与另一矩阵的行数相等,则可定义这两个矩阵的乘积。如 A 是 m×n 矩阵和 B 是 n×p矩阵,它们是乘积 AB 是一个 m×p 矩阵,其中
    (AB)[i, j] = A[i, 1] * B[1, j] + A[i, 2] * B[2, j] + ... + A[i, n] * B[n, j] 对所有 i 及 j。
    此乘法有如下性质:
    (AB)C = A(BC) 对所有 k×m 矩阵 A, m×n 矩阵 B 及 n×p 矩阵 C ("结合律").
    (A + B)C = AC + BC 对所有 m×n 矩阵 A 及 B 和 n×k 矩阵 C ("分配律")。
    C(A + B) = CA + CB 对所有 m×n 矩阵 A 及 B 和 k×m 矩阵 C ("分配律")。
    要注意的是:可置换性不一定成立,即有矩阵 A 及 B 使得 AB ≠ BA。

    下面我们研究一下这道题如何运用矩阵。

    f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
    构造的矩阵是:

    |0 1 0 ......... 0|    |f0|   |f1 |
    |0 0 1 0 ....... 0|    |f1|   |f2 |
    |................1| *  |..| = |...|
    |a9 a8 .........a0|    |f9|   |f10|

    */

    我们看到规律了,每次要到下次个A*B,以此类推则由A*A*A.......A*B;

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn = 15;
     6 int k, mod;
     7 
     8 struct MT{
     9     int m[maxn][maxn];
    10 };
    11 
    12 MT Mul(MT a, MT b)
    13 {
    14     MT res;
    15     memset(res.m, 0, sizeof(res.m));
    16 
    17     for(int i = 0; i < 10; i++)
    18     {
    19         for(int j = 0; j < 10; j++)
    20         {
    21             for(int k = 0; k < 10; k++)
    22             {
    23                 res.m[i][j] += a.m[i][k]*b.m[k][j] % mod;
    24             }
    25             res.m[i][j] %= mod;
    26         }
    27     }
    28     return  res;
    29 }
    30 
    31 MT Product(MT a, int k)
    32 {
    33     MT r;
    34     memset(r.m, 0, sizeof(r.m));
    35     for(int i = 0; i < 10; i++)
    36     {
    37         r.m[i][i] = 1;
    38     }
    39 
    40     while(k)
    41     {
    42         if(k & 1) r = Mul(r, a);
    43         k >>= 1;
    44         a = Mul(a, a);
    45     }
    46 
    47     return r;
    48 }
    49 
    50 int main()
    51 {
    52     MT a;
    53     while(~scanf("%d %d", &k, &mod))
    54     {
    55         for(int i = 0; i < 9; i++)
    56         {
    57             for(int j = 0; j < 10; j++)
    58             {
    59                 if(j == i + 1) a.m[i][j] = 1;
    60                 else a.m[i][j] = 0;
    61             }
    62         }
    63 
    64         for(int i = 9; i >= 0; i--)
    65         {
    66             scanf("%d", &a.m[9][i]);
    67         }
    68 
    69         if(k <= 9)
    70         {
    71             printf("%d
    ", k % mod);
    72             continue;
    73         }
    74 
    75         int ans = 0;
    76         MT b = Product(a, k-9);
    77 
    78         for(int i = 0; i < 10; i++)
    79         {
    80             ans += b.m[9][i]*i % mod;
    81         }
    82 
    83         printf("%d
    ", ans % mod);
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    关于VGG网络的介绍
    nvidia-docker 安装
    test
    ARTS-S EN0002-London HIV patient's remission spurs hope for curing AIDS
    ARTS-S EN0001-In tech race with China, US universities may lose a vital edge
    ARTS-S Why do India and Pakistan keep fighting over Kashmir?
    ARTS-S sed指定行添加
    ARTS-S linux查看进程打开的文件数
    ARTS-S centos查看端口被哪个进程占用
    ARTS-S centos修改hostname
  • 原文地址:https://www.cnblogs.com/loveprincess/p/4946109.html
Copyright © 2020-2023  润新知