思路:c++
fn = can * f1xn * f2yn * f3zn, 首先dp計算指數部分an = an-1 + an-2 + an-3 + 2 * n - 6, 而an-1 = an-2 + an-3 + an-4 + 2 * n - 8,相減能夠獲得an = 2 * an-1 - an-4 + 2。xn,yn和zn是普通的三階斐波那契。計算完指數部分要對p - 1取模(由費馬小定理知p爲質數的狀況ap - 1 % p = 1),而後再用快速冪計算各個部分相乘便可。spa
再記錄一種兩個互相交互的遞推式的矩陣快速冪構造:code
實現:blog
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 typedef vector<vector<ll>> matrix; 6 7 const ll mod = 1e9 + 7, p_mod = mod - 1; 8 9 matrix mat_mul(matrix & a, matrix & b) 10 { 11 matrix c(a.size(), vector<ll>(b[0].size())); 12 for (int i = 0; i < a.size(); i++) 13 { 14 for (int k = 0; k < a[0].size(); k++) 15 { 16 for (int j = 0; j < b[0].size(); j++) 17 { 18 c[i][j] = ((c[i][j] + a[i][k] * b[k][j] % p_mod) + p_mod) % p_mod; 19 } 20 } 21 } 22 return c; 23 } 24 25 matrix mat_pow(matrix & a, ll n) 26 { 27 matrix res(a.size(), vector<ll>(a[0].size())); 28 for (int i = 0; i < a.size(); i++) res[i][i] = 1; 29 while (n > 0) 30 { 31 if (n & 1) res = mat_mul(res, a); 32 a = mat_mul(a, a); 33 n >>= 1; 34 } 35 return res; 36 } 37 38 ll pow(ll x, ll n) 39 { 40 ll res = 1; 41 while (n > 0) 42 { 43 if (n & 1) res = res * x % mod; 44 x = x * x % mod; 45 n >>= 1; 46 } 47 return res; 48 } 49 50 int main() 51 { 52 ll n, f1, f2, f3, c; 53 while (cin >> n >> f1 >> f2 >> f3 >> c) 54 { 55 matrix x(5, vector<ll>(5, 0)), a(5, vector<ll>(1, 0)); 56 x[0][0] = 2; x[0][3] = -1; x[0][4] = 2; 57 x[1][0] = x[2][1] = x[3][2] = x[4][4] = 1; 58 a[0][0] = 2; a[4][0] = 1; 59 matrix c_p = mat_pow(x, n - 4); 60 c_p = mat_mul(c_p, a); 61 matrix y(3, vector<ll>(3, 0)), b1(3, vector<ll>(1, 0)), b2(3, vector<ll>(1, 0)), b3(3, vector<ll>(1, 0)); 62 y[0][0] = y[0][1] = y[0][2] = y[1][0] = y[2][1] = 1; 63 b1[2][0] = b2[1][0] = b3[0][0] = 1; 64 matrix t = mat_pow(y, n - 3); 65 matrix f1_p = mat_mul(t, b1); 66 matrix f2_p = mat_mul(t, b2); 67 matrix f3_p = mat_mul(t, b3); 68 ll ans = 1; 69 ans = ans * pow(c, c_p[0][0]) % mod; 70 ans = ans * pow(f1, f1_p[0][0]) % mod; 71 ans = ans * pow(f2, f2_p[0][0]) % mod; 72 ans = ans * pow(f3, f3_p[0][0]) % mod; 73 cout << ans << endl; 74 } 75 return 0; 76 }