CF1182E Product Oriented Recurrence

思路:

f= can * f1xn * f2yn * f3zn, 首先dp计算指数部分a= an-1 + an-2 + an-3 + 2 * n - 6, 而an-1 = an-2 + an-3 + an-4 + 2 * n - 8,相减可以得到a= 2 * an-1 - an-4 + 2。xn,yn和zn是普通的三阶斐波那契。计算完指数部分要对p - 1取模(由费马小定理知p为质数的情况ap - 1 % p = 1),然后再用快速幂计算各个部分相乘即可。

再记录一种两个互相交互的递推式的矩阵快速幂构造:

                    

实现:

 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 }
原文地址:https://www.cnblogs.com/wangyiming/p/11010327.html