害,我竟无言以对
题目:
http://acm.zzu.edu.cn/problem.php?cid=1048&pid=10
问题 K: 小L进阶的斐波那契数列游戏
时间限制: 1 Sec 内存限制: 128 MB
提交: 21 解决: 11
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述
小L觉得普通斐波那契数列太无聊了,于是他决定研究一下高端玩法,比如斐波那契前n项的平方和。
输入
一个整数n(n<=1e15)。
输出
一个整数,表示斐波那契数列的前n项和对1000000007取模后的值。
样例输入
4
样例输出
15
[提交][状态]
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1000000007;
ll anns;
/*
*加强版斐波那契数列*
已知F(1)=F(2)=1,F[n]=F(n-1)+F(n-2),(n>2).
怎么推出这个数列的关系矩阵?
F(n) F(n-1)+F(n-2) 1 1 F(n-1) 1 1 F(2)
[ ] = [ ] = [ ] * [ ] = [ ]^n-2 *[ ]
F(n-1) F(n-1) 1 0 F(n-2) 1 0 F(1)
得到关系矩阵 1 1
M = [ ]
1 0
*/
//矩阵快速幂板子
struct M {ll a[2][2];};
M ans;
M Matrix(M a,M b) //a*b
{
M c;
memset(c.a,0,sizeof(c.a));
for(ll i=0;i<2;i++){
for(ll j=0;j<2;j++){
for(ll k=0;k<2;k++)
{
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
}
}
}
return c;
}
M jzpowm(M a,ll b) //a^b
{
memset(ans.a,0,sizeof(ans.a));
for(ll i=0;i<2;i++) ans.a[i][i]=1;//单位矩阵
while(b)
{
if(b&1) ans=Matrix(ans,a);
a=Matrix(a,a);
b/=2;
}
return ans;
}
ll solve(ll dd){
ll jieguo;
if(dd<=2) jieguo=1;
else{
M xm;
xm.a[0][0]=1,xm.a[0][1]=1,xm.a[1][0]=1,xm.a[1][1]=0;
M m;
m=jzpowm(xm,dd-2);
ll jg=(m.a[0][0]%mod+m.a[0][1]%mod)%mod;
jieguo=jg;
}
return jieguo;
}
int main()
{
ll n;
cin>>n;
anns=(solve(n)*solve(n+1))%mod;
cout<<anns<<" ";
return 0;
}