FIB Query
Time Limit : 6000/2000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other)
Total Submission(s) : 37 Accepted Submission(s) : 9
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
We all know the definition of Fibonacci series: fib[i]=fib[i-1]+fib[i-2],fib[1]=1,fib[2]=1.And we define another series P associated with the Fibonacci series: P[i]=fib[4*i-1].Now we will give several queries about P:give two integers L,R, and calculate ∑P[i](L <= i <= R).
Input
There is only one test case.
The first line contains single integer Q – the number of queries. (Q<=10^4)
Each line next will contain two integer L, R. (1<=L<=R<=10^12)
The first line contains single integer Q – the number of queries. (Q<=10^4)
Each line next will contain two integer L, R. (1<=L<=R<=10^12)
Output
For each query output one line.
Due to the final answer would be so large, please output the answer mod 1000000007.
Due to the final answer would be so large, please output the answer mod 1000000007.
Sample Input
2
1 300
2 400
Sample Output
838985007
352105429
令Sum[i]=sigma{P[j]}1<=j<=i,显然对于最终答案即为Sum[r]-Sum[l-1],所以我们只需关注Sum[i]的高效解法。
Sum[i]=Fib[3]+Fib[7]+......+Fib[4i-1],
因为Fib[m+n-1]=Fib[m-1]*Fib[n-1]+Fib[m]*Fib[n]
所以Fib[4i-1]=Fib[2i+2i-1]=Fib[2i-1]*Fib[2i-1]+Fib[2i]*Fib[2i]
所以Sum[i]=Fib[1]*Fib[1]+Fib[2]*Fib[2]+......+Fib[2i]*Fib[2i]
又Fib[i]*Fib[i+1]+Fib[i+1]*Fib[i+1]=Fib[i+1]*Fib[i+2]
代入计算可得Sum[i]=Fib[2i]*Fib[2i+1]-Fib[0]*Fib[1]=Fib[2i]*Fib[2i+1]
最后发现Sum[i]只和fibonacci的两项有关。
关于fibonacci数列的一项可以构造矩阵在O(logn)时间内算出。
Sum[i]=Fib[3]+Fib[7]+......+Fib[4i-1],
因为Fib[m+n-1]=Fib[m-1]*Fib[n-1]+Fib[m]*Fib[n]
所以Fib[4i-1]=Fib[2i+2i-1]=Fib[2i-1]*Fib[2i-1]+Fib[2i]*Fib[2i]
所以Sum[i]=Fib[1]*Fib[1]+Fib[2]*Fib[2]+......+Fib[2i]*Fib[2i]
又Fib[i]*Fib[i+1]+Fib[i+1]*Fib[i+1]=Fib[i+1]*Fib[i+2]
代入计算可得Sum[i]=Fib[2i]*Fib[2i+1]-Fib[0]*Fib[1]=Fib[2i]*Fib[2i+1]
最后发现Sum[i]只和fibonacci的两项有关。
关于fibonacci数列的一项可以构造矩阵在O(logn)时间内算出。
-------哈工程的解题报告
//源代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
using namespace std;
void Juzhen(__int64 a[][2], __int64 b[][2]){
__int64 ans[2][2];
ans[0][0] = (a[0][0] * b[0][0] % 1000000007 + a[0][1] * b[1][0] % 1000000007) % 1000000007;
ans[0][1] = (a[0][0] * b[0][1] % 1000000007 + a[0][1] * b[1][1] % 1000000007) % 1000000007;
ans[1][0] = (a[1][0] * b[0][0] % 1000000007 + a[1][1] * b[1][0] % 1000000007) % 1000000007;
ans[1][1] = (a[1][0] * b[0][1] % 1000000007 + a[1][1] * b[1][1] % 1000000007) % 1000000007;
a[0][0] = ans[0][0], a[0][1] = ans[0][1], a[1][0] = ans[1][0], a[1][1] = ans[1][1];
}
__int64 fbnq(__int64 num){
if(num == 0) return 0;
__int64 a[2][2] = {1, 0, 0, 1};
__int64 b[2][2] = {1, 1, 1, 0};
while (num > 1){
if ((num&1) != 0) Juzhen(a,b);
Juzhen(b,b);
num >>= 1;
}
Juzhen(b,a);
return b[0][1];
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
__int64 L,R;
__int64 suml = 0,sumr = 0;
scanf("%I64d %I64d",&L,&R);
L--;
suml = fbnq(2*L) * fbnq(2*L+1);
sumr = fbnq(2*R) * fbnq(2*R+1);
printf("%d\n",((sumr-suml) % 1000000007 + 1000000007) % 1000000007);
}
}