【SP8001】Fibonacci Sum

斐波那契数列是一个人们所熟知的序列,不多赘述。

直接求题面中给出的 \(\sum\limits_{i=N}^MF_i\) 似乎很没有思路,我们运用前缀和的思想,得到 \(\sum\limits_{i=N}^MF_i=\left(\sum\limits_{i=1}^MF_i\right)-\left(\sum\limits_{i=1}^{N-1}F_i\right)\),容易发现,右边这两坨形式是一样的。

问题转化成求形如 \(\sum\limits_{i=1}^{n} F_i\) 的值。

我们来推个式子:

\[\begin{aligned} &\; \; \; \; \; F_{n} \\ &= F_{n-1}+F_{n-2} \\ &= F_{n-2}+F_{n-3}+F_{n-4}+F_{n-3}\\ &= F_{n-2}+F_{n-3}+F_{n-4}+F_{n-5}+F_{n-6}+F_{n-5}\\ &= \cdots \end{aligned} \]

不难发现,经过有限次推导,式子最后一项会变成 \(F_1\)\(F_2\)

又有 \(F_1=F_2=1\),则得到式子 \(F_n=\left(\sum\limits_{i=1}^{n-2}F_{i}\right)+1\)

则回到要求的式子,\(\sum\limits_{i=1}^nF_i=F_{n+2}-1\)

通过矩阵快速幂优化递推,我们可以在 \(O(\log n)\) 的复杂度内求出 \(F_{n+2}\),减一后得到结果。

再将此带回最原始的式子,问题得解。

#include <stdio.h>
#include <string.h>
const int MAXN=2,mod=1000000007;
template<const size_t n=MAXN>class Matrix
{
private:
	int i,j,k;
	long long temp[n][n];
public:
	long long f[n][n];
	Matrix()
	{
		for(i=0;i<n;++i)
			for(j=0;j<n;++j)
			{
				f[i][j]=i==j;
			}
	}
	inline const Matrix &operator*=(const Matrix &other)
	{
		for(i=0;i<n;++i)
			for(j=0;j<n;++j)
			{
				temp[i][j]=0;
			}
		for(i=0;i<n;++i)
			for(j=0;j<n;++j)
				for(k=0;k<n;++k)
					(temp[i][j]+=f[i][k]*other.f[k][j])%=mod;
		for(i=0;i<n;++i)
			for(j=0;j<n;++j)
			{
				f[i][j]=temp[i][j];
			}
		return *this;
	}
};
long long get(long long x){
	int t;
	long long X;
	if(x<3)
		return 1;
	else{
		Matrix<MAXN> ans;
		Matrix<MAXN> base;
		base.f[0][0]=1;base.f[0][1]=1;
		base.f[1][0]=1;base.f[1][1]=0;
		ans.f[0][0]=ans.f[0][1]=1;
		X=x-2;
		while(X){
			if(X&1)
				ans*=base;
			base*=base;
			X>>=1;
		}
	return ans.f[0][0];
	}
}
int main()
{long long n,m;
	int t;scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld",&n,&m);
		printf("%lld\n",((get(m+2)-1)-((get(n+1)-1))%mod+mod)%mod);
	}
	return 0;
}
posted @ 2023-02-24 21:29  Syara  阅读(20)  评论(0编辑  收藏  举报