uva 10870
Posted Omz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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\n",f[n-1] % m); 84 85 continue; 86 } 87 88 solve(p,n-d); 89 } 90 91 return 0; 92 }
以上是关于uva 10870的主要内容,如果未能解决你的问题,请参考以下文章