u‘s的影响力 (矩阵快速幂

该博客介绍了如何利用矩阵快速幂算法解决数列中涉及斐波那契数列和指数运算的复杂计算问题。通过分析数列规律,将斐波那契数列与指数运算结合,提出了矩阵表示和矩阵快速幂的方法,有效避免了大数运算导致的溢出。同时,文章还讨论了欧拉降幂的应用,并提供了相关的C++代码实现。

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

u’s的影响力
题意:
给定一个数列, f ( 1 ) = x , f ( 2 ) = y f(1)=x,f(2)=y f(1)=x,f(2)=y,对于 n > 2 , f ( n ) = f ( n − 1 ) ∗ f ( n − 2 ) ∗ a b n>2,f(n)=f(n-1)*f(n-2)*a^b n>2,f(n)=f(n1)f(n2)ab
f n f_n fn,模 1 e 9 + 7 1e9+7 1e9+7
思路:
f ( 1 ) = x f(1) = x f(1)=x
f ( 2 ) = y f(2)=y f(2)=y
f ( 3 ) = x ∗ y ∗ a b f(3)=x*y*a^b f(3)=xyab
f ( 4 ) = x ∗ y 2 ∗ a 2 b f(4)=x*y^2*a^{2b} f(4)=xy2a2b
f ( 5 ) = x 2 ∗ y 3 ∗ a 4 b f(5)=x^2*y^3*a^{4b} f(5)=x2y3a4b
f ( 6 ) = x 3 ∗ y 5 ∗ a 7 b f(6)=x^3*y^5*a^{7b} f(6)=x3y5a7b
手写前几个 f ( x ) f(x) f(x) 可以找出规律,从第三项开始 x , y x,y x,y 的次幂都是斐波那契数列 ( 1 , 1 , 2 , 3 , 5... ) (1,1,2,3,5...) (1,1,2,3,5...) 的某一项,然后 a a a 的次幂也是递推的,递推式 f n = f n − 1 + f n − 2 + 1 f_n=f_{n-1}+f_{n-2}+1 fn=fn1+fn2+1 ,然后求一下系数矩阵,也可以用矩阵快速幂求得 b b b 的系数。
但是要注意次幂显然是非常大,而且远大于 φ ( p ) \varphi(p) φ(p) 的,因此还需要欧拉降幂
注意如果 x , y , a x,y,a x,y,a m o d mod mod 不互质时直接输出 0 0 0 即可
最后计算答案即可
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 3;

ll n, x, y, a, b;
struct mat{
	ll m[N][N];
	mat(){
		memset(m, 0, sizeof(m));
	}
};
mat mul(mat a, mat b, ll mo = mod - 1){
	mat tmp;
	for(int i = 0; i < N; ++i)
		for(int j = 0; j < N; ++j)
			for(int k = 0; k < N; ++k)
				tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j] % mo) % mo;
	return tmp;
}
mat q_pow(mat a, ll b){
	mat ans;
	for(int i = 0; i < N; ++i) ans.m[i][i] = 1;
	while(b){
		if(b & 1){
			ans = mul(ans, a);
		}
		b >>= 1;
		a = mul(a, a);
	}
	return ans;
}
ll q_po(ll a, ll b, ll ans = 1){
	while(b){
		if(b & 1) ans = ans * a % mod;b >>= 1; a = a * a%mod;
	}return ans;
}
void work()
{
	cin >> n >> x >> y >> a >> b;
	x %= mod, y %= mod, a %= mod;// 记得取模一下
	b %= mod - 1;// 注意 b 是次幂,需要mod phi(mod) 
	if(!x || !y || !a){// 特判一下
		cout << 0 << endl;
		return;
	}
	if(n == 1) cout << x << endl;
	else if(n == 2) cout << y << endl;
	else
	{
		mat f;
		f.m[0][0] = f.m[0][1] = 1;
		mat base;
		base.m[0][0] = base.m[1][0] = base.m[0][1] = 1;
		f = mul(f, q_pow(base, n - 3));
		//cout << f.m[0][0] << " " << f.m[0][1] << endl;
		ll ans = q_po(x, f.m[0][1]) * q_po(y, f.m[0][0]) % mod;
		mat ba, st;
		ba.m[0][0] = ba.m[1][0] = ba.m[2][0] = ba.m[0][1] = ba.m[2][2] = 1;
		st.m[0][2] = 1;
		st = mul(st, q_pow(ba, n - 2));
		ans = ans * q_po(a, st.m[0][0] * b % (mod - 1)) % mod;//乘之前b需要模一下,不然爆 ll 
		cout << ans;
	}
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值