zoukankan      html  css  js  c++  java
  • uva 10870

    https://vjudge.net/problem/UVA-10870

    题意:

    f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d

    给出f(1),f(2) ... f(d) 以及a1,a2...ad,然后给出一个n和m的值,计算f(n) % m的值

    思路:

    矩阵快速幂模板题,只是构建矩阵比较困难,其实这题的构建矩阵是比较简单的,这题的模型也是一个相当广泛的模型。

       |a1 a2 a3 a4 a5|                | f[n]     |      | f[n+1] |  
       |1                      |                | f[n-1]  |      | f[n]    |  
       |     1                 |       *        | f[n-2]  | =   | f[n-1] | (空白处为0)
       |          1            |                | f[n-3]  |      | f[n-2] |
       |              1        |                | f[n-4]  |      | f[n-3] |

    就是这样一个关系,可以用手推一下。

    f(n) = A^(n-d) * f(d);

    之后就直接套模板啦。

    最后的f(n)其实是通过得到的结果矩阵的第一行乘以f(d)这个矩阵得到的,只不过乘的时候要关注原矩阵的顺序,别乘反了。

    注意在n <= d的时候是直接取余输出的。(矩阵乘法的时候也要一边乘,一边取余)。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 long long d,n,m;
     5 
     6 long long f[20];
     7 
     8 struct matrix
     9 {
    10     long long a[20][20];
    11 };
    12 
    13 matrix mul(matrix x,matrix y)
    14 {
    15     matrix c;
    16 
    17     for (int i = 0;i < d;i++)
    18         for (int j = 0;j < d;j++)
    19     {
    20         c.a[i][j] = 0;
    21 
    22         for (int k = 0;k < d;k++)
    23         {
    24             c.a[i][j] = (c.a[i][j] + x.a[i][k] * y.a[k][j] % m) % m;
    25         }
    26     }
    27 
    28     return c;
    29 }
    30 
    31 void solve(matrix t,long long o)
    32 {
    33     matrix e;
    34 
    35     memset(e.a,0,sizeof(e.a));
    36 
    37     for (int i = 0;i < d;i++)
    38         e.a[i][i] = 1;
    39 
    40     while (o)
    41     {
    42         if (o & 1)
    43         {
    44             e = mul(e,t);
    45         }
    46 
    47         o >>= 1;
    48 
    49         t = mul(t,t);
    50     }
    51 
    52     long long res = 0;
    53 
    54     for (int i = 0;i < d;i++)
    55         res = (res + e.a[0][i] * f[d-i-1]) % m;
    56 
    57     printf("%lld
    ",res);
    58 }
    59 
    60 int main()
    61 {
    62 
    63 
    64     while (scanf("%lld%lld%lld",&d,&n,&m) != EOF)
    65     {
    66         if (d == 0 && n == 0 && m == 0) break;
    67 
    68         matrix p;
    69 
    70         memset(p.a,0,sizeof(p.a));
    71 
    72         for (int i = 0;i < d;i++)
    73             scanf("%lld",&p.a[0][i]);
    74 
    75         for (int i =  1;i < d;i++)
    76             p.a[i][i-1] = 1;
    77 
    78         for (int i = 0;i < d;i++)
    79             scanf("%lld",&f[i]);
    80 
    81         if (n <= d)
    82         {
    83             printf("%lld
    ",f[n-1] % m);
    84 
    85             continue;
    86         }
    87 
    88         solve(p,n-d);
    89     }
    90 
    91     return 0;
    92 }
  • 相关阅读:
    c++笔试题3
    C++笔试题
    C++编程指南续(10-11)
    C++详解(8-9)
    C++编程指南(6-7)
    C++编程指南续(4-5)
    C++编程指南续
    C++的编程指南
    HPSocket介绍与使用
    WinForm中TreeView控件实现鼠标拖动节点(可实现同级节点位置互换,或拖到目标子节点)
  • 原文地址:https://www.cnblogs.com/kickit/p/7287166.html
Copyright © 2011-2022 走看看