Question Link
Question: F (k) % m
Thought: f (x) = A0 * F (x-1) + A1 * F (X-2) + A2 * F (X-3) + ...... + A9 * F (X-10), so we can get a Matrix
(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)
(1, 0, 0, 0, 0, 0, 0, 0, 0)
(0, 1, 0, 0, 0, 0, 0, 0, 0)
(0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
(0, 0, 0, 1, 0, 0, 0, 0, 0)
(0, 0, 0, 0, 1, 0, 0, 0, 0)
(0, 0, 0, 0, 0, 1, 0, 0, 0)
(0, 0, 0, 0, 0, 0, 1, 0, 0)
(0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
(0, 0, 0, 0, 0, 0, 0, 0, 1, 0 )*
| F (x-1), F (x-2), F (x-3), F (x-4), F (x-5 ), f (x-6), F (x-7), F (x-8), F (x-9), F (x-10) | =
| F (x), F (x-1), F (x-2), F (x-3), F (x-4 ), f (x-5), F (x-6), F (x-7), F (x-8), F (x-9) |
Use a matrix to quickly calculate a power.
Code:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef __int64 ll;const int N = 10;ll k, m;struct mat{ ll s[N][N]; mat() { sizeof(s, 0, sizeof(s)); } mat operator * (const mat& c) { mat ans; memset(ans.s, 0, sizeof(ans.s)); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < N; k++) ans.s[i][j] = (ans.s[i][j] + s[i][k] * c.s[k][j]) % m; return ans; }};mat state, tmp;void init() { for (int i = 0; i < 10; i++) tmp.s[i][0] = 9 - i; for (int i = 0; i < 10; i++) scanf("%I64d", &state.s[0][i]); for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) if (i - 1 == j) state.s[i][j] = 1;}mat pow_mod(ll k) { if (k == 1) return state; mat a = pow_mod(k / 2); mat ans = a * a; if (k % 2 == 1) ans = ans * state; return ans;}int main() { while (scanf("%I64d%I64d", &k, &m) != EOF) { if (k < 10) printf("%I64d\n", k % m); else { init(); mat ans = pow_mod(k - 9); ans = ans * tmp; printf("%I64d\n", ans.s[0][0]); } } return 0;}
HDU1757-A simple math problem (matrix fast power)