题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), for n > d.
已知前d项求第n项
思路:矩阵快速幂,对应矩阵为
|a1 a2 a3 ... ad|
|1 0 0 ... 0 0 0|
|0 1 0 ... 0 0 0|
|0 0 1 ... 0 0 0|
|0 0 0 ... 0 0 0|
|0 0 0 ... 1 0 0|
|0 0 0 ... 0 1 0|
|0 0 0 ... 0 0 1|
代码:
#include <stdio.h> #include <string.h> const int N = 20; long long d, n, m, f[N]; struct mat { long long n, v[N][N]; mat(long long n = 0) { this->n = n; memset(v, 0, sizeof(v)); } mat operator * (mat b) { mat ans = mat(n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { ans.v[i][j] = ((ans.v[i][j] + v[i][k] * b.v[k][j] % m) % m + m) % m; } } } return ans; } }; mat pow_mod(mat a, long long k) { mat ans(a.n); for (int i = 0; i < ans.n; i++) ans.v[i][i] = 1; while (k) { if (k&1) ans = ans * a; a = a * a; k >>= 1; } return ans; } int main() { while (~scanf("%lld%lld%lld", &d, &n, &m) && d) { mat a = mat(d); for (int i = 0; i < d; i++) scanf("%lld", &a.v[0][i]); for (int i = 1; i < d; i++) a.v[i][i - 1] = 1; for (int i = 0; i < d; i++) scanf("%lld", &f[i]); if (n <= d) printf("%lld\n", f[n - 1]); else { long long ans = 0; a = pow_mod(a, n - d); for (int i = 0; i < d; i++) ans = (ans + (f[d - i - 1] * a.v[0][i] % m + m)) % m; printf("%lld\n", ans); } } return 0; }
UVA 10870 - Recurrences(矩阵快速幂),布布扣,bubuko.com
UVA 10870 - Recurrences(矩阵快速幂)
原文地址:http://blog.csdn.net/accelerator_/article/details/37990589