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}\),用矩阵快速幂求解即可。
程序
#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;
}

浙公网安备 33010602011771号