洛谷 P1349 广义斐波那契数列(矩阵快速幂, 水题)

这篇博客介绍了如何运用矩阵快速幂方法解决广义斐波那契数列的模运算问题。给定数列的系数p和q,初始项a1和a2,以及求解的项数n和模数m,要求求出数列的第n项an对m取模的结果。样例展示了具体的操作过程,并强调了数据范围和限制条件。

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

广义斐波那契数列

题目描述

广义的斐波那契数列是指形如 a n = p × a n − 1 + q × a n − 2 a_n=p\times a_{n-1}+q\times a_{n-2} an=p×an1+q×an2 的数列。
今给定数列的两系数 p p p q q q,以及数列的最前两项 a 1 a_1 a1 和$ a_2$,另给出两个整数 n n n m m m,试求数列的第 n n n a n   m o d   m a_n \bmod m anmodm

输入格式

输入包含一行六个整数, p , q , a 1 , a 2 , n , m p,q,a_1,a_2,n,m p,q,a1,a2,n,m

输出格式

输出包含一行一个整数表示答案。

样例 #1

样例输入 #1

1 1 1 1 10 7

样例输出 #1

6

提示

数列第 $10 $项是 55 55 55 55   m o d   7 = 6 55 \bmod 7 = 6 55mod7=6

【数据范围】
对于 100 % 100\% 100% 的数据, p , q , a 1 , a 2 ∈ [ 0 , 2 31 − 1 ] p,q,a_1,a_2 \in [0,2^{31}-1] p,q,a1,a2[0,2311] 1 ≤ n , m ≤ 2 31 − 1 1\le n,m \le 2^{31}-1 1n,m2311

1、矩阵乘法, 矩阵快速幂
	(f[2], f[3]) = (f[1], f[2]) * A,  A 是矩阵,
	A[1][1]=0 A[1][2]=q
	A[2][1]=1 A[2][2]=p
2、 n >= 3 时候, (f[n-1], f[n]) = (f[1], f[2]) * A^(n-2)
	先算出 A^(n-2), 最后结果就是 
	f[n] = f[1] * A[1][2] + f[2] * A[2][2]
3、 全部数据用 long long , 一步到位
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef long long ll;
ll p, q, a1, a2, n, mod;

struct matrix
{
	ll c[3][3];
	matrix()
	{
		memset(c, 0, sizeof c);
	}
};

matrix R;

matrix multi(matrix& x, matrix& y)
{
	matrix r;
	for(int i = 1; i <= 2; ++i)
	{
		for(int j = 1; j <= 2; ++j)
		{
			for(int k = 1; k <= 2; ++k)	
			{
				r.c[i][j] += (x.c[i][k] % mod) * (y.c[k][j] % mod) % mod;
				r.c[i][j] %= mod;
			}
		}
	}
	return r;
}

matrix quick_pow(matrix A, ll k)
{
	matrix res;
	for(int i = 1; i <= 2; ++i)
		res.c[i][i] = 1;
	while(k)
	{
		if(k & 1)
		{
			res = multi(res, A);
		}

		A = multi(A, A);
		k >>= 1;
	}
	return res;
}

int main()
{
	scanf("%lld%lld%lld%lld%lld%lld", &p, &q, &a1, &a2, &n, &mod);
	if(n == 1)
	{
		printf("%lld\n", a1 % mod);
		return 0;
	}
	if(n == 2)
	{
		printf("%lld\n", a2 % mod);
		return 0;
	}
	R.c[1][1] = 0,  R.c[1][2] = q, R.c[2][1] = 1, R.c[2][2] = p;
	R = quick_pow(R, n - 2);
	ll t1 = ((R.c[1][2] % mod) * (a1 % mod)) % mod; 
	ll t2 = ((R.c[2][2] % mod) * (a2 % mod)) % mod; 
	ll ans = (t1 + t2) % mod;
	printf("%lld\n", ans);
	return 0;
}

/*
1 1 1 1 10 7
*/

/*
6
*/

### C++ 实现斐波那契数列矩阵快速幂 为了高效计算大项的斐波那契数值,可以采用矩阵快速幂算法。该方法利用了斐波那契数列相邻两项之间的线性关系: \[ \begin{bmatrix} F(n) \\ F(n-1) \end{bmatrix} = M^{n-1} * \begin{bmatrix} 1 \\ 0 \end{bmatrix},\quad where\;M=\begin{bmatrix} 1 & 1\\ 1& 0 \end{bmatrix}\] 通过这种方式可以在 \(O(\log n)\) 时间复杂度内完成计算。 下面是一个完整的 C++ 程序来展示如何实现这一过程: ```cpp #include <iostream> using namespace std; struct Matrix { long long mat[2][2]; }; Matrix multiply(const Matrix& A, const Matrix& B){ Matrix result; for(int i=0;i<2;++i) for(int j=0;j<2;++j){ result.mat[i][j]=0; for(int k=0;k<2;++k) result.mat[i][j]+=(A.mat[i][k]*B.mat[k][j])%1000000007; result.mat[i][j]%=1000000007; } return result; } // 快速幂函数用于加速矩阵乘法运算 Matrix power(Matrix base,long exp){ Matrix res={{1,0},{0,1}};//单位阵初始化 while(exp>0){ if(exp&1)//如果exp为奇数,则多做一次乘法操作 res=multiply(res,base); base=multiply(base,base);//平方基数 exp>>=1;//右移一位相当于除以二 } return res; } long fibonacci(long N){ if(N==0)return 0; Matrix initial{{1,1},{1,0}}; Matrix powered_matrix=power(initial,N-1); return powered_matrix.mat[0][0]%1000000007; } ``` 此程序定义了一个 `multiply` 函数来进行两个矩阵相乘的操作,并且实现了 `power` 方法用来执行高效的矩阵指数运算。最后,在 `fibonacci` 函数里调用了这些辅助功能并返回第N个斐波那契数的结果[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值