SP8001 Fibonacci Sum

Luogu 链接
SPOJ 链接
Virtual Judge 链接

题意

题目描述

定义一个数列 \(\{F_n\}\)

\[F_n=\begin{cases} 0,&n=0\\ 1,&n=1\\ F_{n-1}+F_{n-2},&n\ge2 \end{cases}\]

(其实就是斐波那契数列)
现给出两个正整数 \(n\)\(m\),求 \(\displaystyle\sum_{i=n}^mF_i\)
由于答案很大,你只需输出其对 \(10^9+7\) 取模后的结果。


输入格式

多测,第一行一个正整数 \(T\)\(T\le10^3\)),代表组数。
每组数据一行两个正整数 \(n\)\(m\)\(0\le n\le m\le10^9\)),含义见题目描述


输出格式

题目描述

思路

\(\displaystyle S_n=\sum_{i=0}^nF_i\),则所求即为 \(S_m-S_{n-1}\)(为了方便讨论,令 \(S_{-1}=0\))。

接下来看看 \(S_n\) 有什么规律。

\[\begin{aligned} &S_{-1}=0=F_{-1+2}-1\\ &S_0=0=F_{0+2}-1\\ &S_1=1=F_{1+2}-1\\ &S_2=2=F_{2+2}-1\\ &S_3=4=F_{3+2}-1\\ &S_4=7=F_{4+2}-1\\ &S_4=12=F_{5+2}-1\\ \end{aligned}\]

可以猜测 \(S_n=F_{n+2}-1\)

以下为这一结论的证明:

\(n=-1\) 时,有 \(S_{-1}=F_{-1+2}-1=0\),成立;
\(n=k-1\)\(k\ge0\))时成立,有

\[\begin{aligned}S_{k}&=S_{k-1}+F_k\\&=F_{k+1}-1+F_k\\&=F_{k+2}-1\end{aligned} \]

\(S_n=F_{n+2}-1\)\(\forall n\ge-1,n\in\mathbb Z\) 成立。

故原式化为 \(F_{m+2}-F_{n+1}\),用矩阵快速幂求解即可。

程序

AC 记录

#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<iomanip>
#include<string>
#include<stack>
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define vl __int128
#define ld long double
#define INF 0x3f3f3f3f
#define ls rt<<1
#define rs rt<<1|1
#define lb(x) ((x)&(-(x)))
#define pb push_back
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int N=500+10;const ll mod=1e9+7;
//#define use_file
#define more_test
//#define need_init
#ifdef more_test
int T;
#endif

struct matrix{
	ll a,b,c,d;
	matrix(){a=1,b=0,c=0,d=1;}
	matrix(ll A,ll B,ll C,ll D){a=A,b=B,c=C,d=D;}
};
matrix mul(const matrix& m1,const matrix& m2){
	matrix ans;
	ans.a=(m1.a*m2.a+m1.b*m2.c)%mod;
	ans.b=(m1.a*m2.b+m1.b*m2.d)%mod;
	ans.c=(m1.c*m2.a+m1.d*m2.c)%mod;
	ans.d=(m1.c*m2.b+m1.d*m2.d)%mod;
	return ans;
}
ll pow(ll n){
	--n;
	if(n<=1)return 1;
	matrix ans,p(1,1,1,0);
	while(n){
		if(n&1)ans=mul(ans,p);
		p=mul(p,p);
		n>>=1;
	}
	return ans.a;
}

ll n,m;

ll ans1,ans2;

void SOLVE(int TestID){
	scanf("%lld%lld",&n,&m);
	ans1=pow(n+1),ans2=pow(m+2);
	printf("%lld\n",(ans2-ans1+mod)%mod);
}
/*
Input:

Output:

*/
int main(){
	#ifdef use_file
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	#endif
	#ifdef need_init
	init();
	#endif
	#ifdef more_test
	scanf("%d",&T);
	for(int i=1;i<=T;++i)SOLVE(i);
	#else
	SOLVE();
	#endif
	return 0;
}
posted @ 2025-04-05 19:29  LXcjh4998  阅读(15)  评论(0)    收藏  举报