description
Let
f
x
=
c
2
x
−
6
⋅
f
x
−
1
⋅
f
x
−
2
⋅
f
x
−
3
f_{x} = c^{2x-6} \cdot f_{x-1} \cdot f_{x-2} \cdot f_{x-3}
fx=c2x−6⋅fx−1⋅fx−2⋅fx−3 for
x
≥
4
x \geq 4
x≥4
You have given integers
n
n
n,
f
1
f_1
f1,
f
2
f_2
f2,
f
3
f_3
f3, and
c
c
c. Find
f
n
m
o
d
(
1
0
9
+
7
)
f_n ~mod~(10^9+7)
fn mod (109+7).
Input
The only line contains five integers n n n, f 1 f_1 f1, f 2 f_2 f2, f 3 f_3 f3, and c c c ( 4 ≤ n ≤ 1 0 18 , 1 ≤ f 1 , f 2 , f 3 , c ≤ 1 0 9 4≤n≤10^{18}, 1≤f_1, f_2, f_3, c≤10^9 4≤n≤1018,1≤f1,f2,f3,c≤109).
Output
Print f n m o d ( 1 0 9 + 7 ) {f_n~mod~(10^9+7)} fn mod (109+7).
Examples
Input
5 1 2 5 3
Output
72900
Input
17 97 41 37 11
Output
317451037
分析
对原式子两边取对数,有
l
n
f
x
=
(
2
x
−
6
)
⋅
l
n
c
+
l
n
f
x
−
1
+
l
n
f
x
−
2
+
l
n
f
x
−
3
lnf_x=(2x-6)\cdot lnc +lnf_{x-1}+lnf_{x-2}+lnf_{x-3}
lnfx=(2x−6)⋅lnc+lnfx−1+lnfx−2+lnfx−3
可以构造出矩阵,即
(
l
n
f
n
l
n
f
n
−
1
l
n
f
n
−
2
(
2
n
−
4
)
l
n
c
l
n
c
)
=
(
l
n
f
n
−
1
l
n
f
n
−
2
l
n
f
n
−
3
(
2
n
−
6
)
l
n
c
l
n
c
)
(
1
1
0
0
0
1
0
1
0
0
1
0
0
0
0
1
0
0
1
0
0
0
0
2
1
)
\left( \begin{matrix} lnf_n&lnf_{n-1}&lnf_{n-2}&(2n-4)lnc&lnc \end{matrix} \right)= \left( \begin{matrix} lnf_{n-1}&lnf_{n-2}&lnf_{n-3}&(2n-6)lnc&lnc \end{matrix} \right) \left( \begin{matrix} 1&1&0&0&0\\ 1&0&1&0&0\\ 1&0&0&0&0\\ 1&0&0&1&0\\ 0&0&0&2&1 \end{matrix} \right)
(lnfnlnfn−1lnfn−2(2n−4)lnclnc)=(lnfn−1lnfn−2lnfn−3(2n−6)lnclnc)⎝⎜⎜⎜⎜⎛1111010000010000001200001⎠⎟⎟⎟⎟⎞
矩阵快速幂即可。
注意矩阵快速幂取模的时候是对
φ
(
1
e
9
+
7
)
\varphi(1e9+7)
φ(1e9+7) 即
1
e
9
+
6
1e9+6
1e9+6 取模(欧拉定理
代码如下
#include <bits/stdc++.h>
#define LL long long
#define mem(p) memset(&p, 0, sizeof(p))
using namespace std;
const int mod = 1e9 + 7;
const int modd = 1e9 + 6;
struct mat{
LL a[5][5], r, c;
};
LL n, f1, f2, f3, c;
mat mul(mat x, mat y){
mat p;
mem(p);
LL i, j, k;
for(i = 0; i < x.r; i++){
for(j = 0; j < y.c; j++){
for(k = 0; k < x.c; k++)
p.a[i][j] = (p.a[i][j] + x.a[i][k] * y.a[k][j] % modd) % modd;
}
}
p.r = x.r;
p.c = y.c;
return p;
}
LL KSM(LL a, LL b, LL p){
LL s = 1;
while(b){
if(b % 2) s = s * a % mod;
a = a * a % mod;
b /= 2;
}
return s;
}
LL ksm(LL b){
mat ans, p;
mem(ans);
mem(p);
p.a[0][0] = p.a[1][0] = p.a[2][0] = p.a[3][0] = p.a[0][1] = p.a[1][2] = p.a[3][3]
= p.a[4][4] = 1;
p.a[4][3] = 2;
p.c = p.r = 5;
ans = p;
while(b > 0ll){
if(b % 2) ans = mul(ans, p);
p = mul(p, p);
b /= 2;
}
//printf("%lld %lld %lld %lld\n", ans.a[3][0] * 2 + ans.a[4][0], ans.a[2][0], ans.a[1][0], ans.a[0][0]);
return KSM(c, (ans.a[3][0] * 2 % modd + ans.a[4][0]) % modd, mod) * KSM(f1, ans.a[2][0], mod) % mod * KSM(f2, ans.a[1][0], mod) % mod * KSM(f3, ans.a[0][0], mod) % mod;
}
int main(){
int i, j, m;
scanf("%lld%lld%lld%lld%lld", &n, &f1, &f2, &f3, &c);
printf("%lld", (ksm(n - 4) % mod + mod) % mod);
return 0;
}