cf 1182E Product Oriented Recurrence(欧拉定理 + 矩阵快速幂

该博客介绍了如何利用欧拉定理和矩阵快速幂的方法解决给定的线性递推关系问题。给出了具体的问题描述、输入输出格式以及示例。在分析部分,博主解释了通过取对数转换递推公式,并构建矩阵来应用矩阵快速幂求解。最后,提供了实现代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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=c2x6fx1fx2fx3 for x ≥ 4 x \geq 4 x4
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 4n1018,1f1,f2,f3,c109).

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=(2x6)lnc+lnfx1+lnfx2+lnfx3
可以构造出矩阵,即
( 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) (lnfnlnfn1lnfn2(2n4)lnclnc)=(lnfn1lnfn2lnfn3(2n6)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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值