f
x
=
c
2
x
−
6
∗
f
x
−
1
∗
f
x
−
2
∗
f
x
−
3
f_x = c ^ {2x - 6} * f_{x - 1} * f_{x - 2}*f_{x-3}
fx=c2x−6∗fx−1∗fx−2∗fx−3
c
x
f
x
=
c
x
−
1
f
x
−
1
∗
c
x
−
2
f
x
−
2
∗
c
x
−
3
f
x
−
3
c^xf_x = c ^ {x - 1}f_{x - 1} * c^{x-2}f_{x - 2}*c^{x-3}f_{x-3}
cxfx=cx−1fx−1∗cx−2fx−2∗cx−3fx−3令
F
x
=
c
x
∗
f
x
F_x = c ^ x * f_x
Fx=cx∗fx
F
4
=
F
1
∗
F
2
∗
F
3
F_4 = F_1 * F_2 * F_3
F4=F1∗F2∗F3
F
5
=
F
4
∗
F
3
∗
F
2
=
F
1
∗
F
2
2
∗
F
3
2
F_5 = F_4 * F_3 * F_2 = F_1 * F_2 ^2*F_3^2
F5=F4∗F3∗F2=F1∗F22∗F32
F
6
=
F
5
∗
F
4
∗
F
3
=
F
1
2
∗
F
2
3
∗
F
3
4
F_6 = F_5*F_4*F_3=F_1^2*F_2^3*F_3^4
F6=F5∗F4∗F3=F12∗F23∗F34
F
7
=
F
6
∗
F
5
∗
F
4
F_7 = F_6 * F_5 * F_4
F7=F6∗F5∗F4即任意一项
F
x
F_x
Fx都可以转化为
F
1
x
1
∗
F
2
x
2
∗
F
3
x
3
F_1 ^{x_1}*F_2^{x_2}*F_3^{x_3}
F1x1∗F2x2∗F3x3,第7项及以后的项,
x
1
=
(
x
−
1
)
1
+
(
x
−
2
)
1
+
(
x
−
3
)
1
x_1 = (x-1)_1 + (x - 2)_1 + (x-3)_1
x1=(x−1)1+(x−2)1+(x−3)1,对于
x
2
x_2
x2和
x
3
x_3
x3也同样满足。
也就是说它的幂次是一个递推式,可以用矩阵快速幂进行加速,根据欧拉降幂来取模。根据递推式构造3阶递推矩阵,以及幂次的初始矩阵:
F
4
,
F
5
,
F
6
F_4,F_5,F_6
F4,F5,F6的各项幂次构成初始矩阵。
这题就做完了
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
ll a[5][5],tmp[5][5],c[5][5],ans[5][5];
ll b1[5][5],b2[5][5],b3[5][5];
ll n,f1,f2,f3,C;
void mul(ll a[5][5],ll b[5][5],ll p,int n,int m,int c) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= c; j++)
tmp[i][j] = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
for(int k = 1; k <= c; k++)
tmp[i][k] += 1ll * a[i][j] * b[j][k] % p;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= c; j++)
a[i][j] = tmp[i][j];
}
void mfpow(ll a[5][5],ll b,ll p,int n) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
ans[i][j] = i == j;
while(b) {
if(b & 1)
mul(ans,a,p,n,n,n);
b >>= 1;
mul(a,a,p,n,n,n);
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
a[i][j] = ans[i][j];
}
ll fpow(ll a,ll b) {
ll r = 1;
while(b) {
if(b & 1) r = r * a % mod;
a = a * a % mod;
b >>= 1;
}
return r;
}
void solve(ll a[5][5],ll b[5][5],ll p,ll n,ll m,ll c) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
ans[i][j] = a[i][j];
mul(ans,b,p,n,m,c);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= c; j++)
b[i][j] = ans[i][j];
}
int main() {
c[1][1] = c[1][2] = c[1][3] = 1;
c[2][1] = c[3][2] = 1;
b1[1][1] = 2,b1[2][1] = b1[3][1] = 1;
b2[1][1] = 3,b2[2][1] = 2,b2[3][1] = 1;
b3[1][1] = 4,b3[2][1] = 2,b3[3][1] = 1;
ll a1,a2,a3;
scanf("%lld%lld%lld%lld%lld",&n,&f1,&f2,&f3,&C);
f1 = f1 * C % mod;
f2 = f2 * fpow(C,2) % mod;
f3 = f3 * fpow(C,3) % mod;
ll p = fpow(C,n);
ll inv = fpow(p,mod - 2);
n -= 3;
if(n > 3) {
mfpow(c,n - 3,mod - 1,3);
solve(c,b1,mod - 1,3,3,1);
solve(c,b2,mod - 1,3,3,1);
solve(c,b3,mod - 1,3,3,1);
//printf("%lld %lld %lld\n",tmp[1][1],b2[1][1],b3[1][1]);
a1 = fpow(f1,b1[1][1]);
a2 = fpow(f2,b2[1][1]);
a3 = fpow(f3,b3[1][1]);
}
else {
a1 = fpow(f1,b1[3 - n + 1][1]);
a2 = fpow(f2,b2[3 - n + 1][1]);
a3 = fpow(f3,b3[3 - n + 1][1]);
}
printf("%lld\n",a1 * a2 % mod * a3 % mod * inv % mod);
return 0;
}