hdu-3936-FIB Query(斐波那契数列的性质)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3936

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)

 

Output

For each query output one line.
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

题目大意:斐波那契数列:f[n]=f[n-1]+f[n-2];

令:P[n]=f[4*n-1];

给出q对l,r,求P中[l,r]的对1000000007.取模后的值。

斐波那契数列的性质:https://blog.csdn.net/qq_40482358/article/details/81487345

转换成求斐波那契数列的值

转换过程:


		f[1]^2+f[2]^2+f[3]^2+...+f[n]^2=f[n]*f[n+1];
		p[i]=f[4*i-1];
		p[i]=f[2*i-1]^2+f[2*i]^2;
		p[1]=f[1]^2+f[2]^2;
		p[2]=f[3]^2+f[4]^2;
		sum(p[n])=f[1]^2+f[2]^2+f[3]^2+f[4]^2+...+f[2*n-1]^2+f[2*n]^2;
		sum(p[n])=f[2*n]*f[2*n+1];
		F(n)=(1/√5)*{[(1+√5)/2]^(n+1) - [(1-√5)/2]^(n+1)}

用矩阵快速幂求值

矩阵快速幂:

ac:

#include<stdio.h>
#include<string.h>  
#include<math.h>  
  
#include<map>   
//#include<set>
#include<deque>  
#include<queue>  
#include<stack>  
#include<bitset> 
#include<string>  
#include<iostream>  
#include<algorithm>  
using namespace std;  

#define ll long long  
#define INF 0x3f3f3f3f  
#define mod 1000000007
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b) 
#define clean(a,b) memset(a,b,sizeof(a))// 水印 
//std::ios::sync_with_stdio(false);

ll temp[3][3],res[3][3],ans[3][3];

void matrix(ll a[][3],ll b[][3])
{
	clean(temp,0);
	for(int i=1;i<3;++i)
	{
		for(int j=1;j<3;++j)
		{
			for(int k=1;k<3;++k)
				temp[i][j]=(temp[i][j]+a[i][k] * b[k][j])%mod;
		}
	}
	
	for(int i=1;i<3;++i)
	{
		for(int j=1;j<3;++j)
			a[i][j]=temp[i][j]%mod;
	}
}

void quick(ll n)
{
	/*
	矩阵快速幂
	[a,b,c,d] [a,b,c,d];
	[1,1,1,0] [1,1,1,0];
	[a*a+b*c , a*b+b*d , a*c+c*d , b*c+d*d]
	[1+1,1+0,1+0,1+0]  
	
	*/
	clean(ans,0);
	clean(res,0);
	res[1][1]=1;
	res[1][2]=1;
	res[2][1]=1;
	res[2][2]=0;
	for(int i=1;i<3;++i)
	{
		for(int j=1;j<3;++j)
		{
			if(i==j)
				ans[i][j]=1;
			else
				ans[i][j]=0;
		}
	}
	
	while(n)
	{
		if(n&1)
			matrix(ans,res);
		matrix(res,res);
		n=n>>1;
	}
}

int main()
{
	ll n;
	cin>>n;
	for(int i=0;i<n;++i)
	{
		ll l,r;
		cin>>l>>r;
		
		ll ans1=0;
		if(l==2)
			ans1=2;
		if(l>2)
		{
			quick(2*l-2-2);
			ans1=(ans[1][1]+ans[2][1])%mod;
			quick(2*l-2-2+1);
			ans1=(ans1*((ans[1][1]+ans[2][1])%mod))%mod;
		}
		ll ans2=0;
		quick(2*r-2);
		ans2=(ans[1][1]+ans[2][1])%mod;
		quick(2*r-2+1);
		ans2=(ans2*((ans[1][1]+ans[2][1])%mod))%mod;
		cout<<(ans2-ans1+mod)%mod<<endl;
		
		
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/81487297