本文主要是介绍Cogs 1708. 斐波那契平方和(矩阵乘法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- 斐波那契平方和
★★☆ 输入文件:fibsqr.in 输出文件:fibsqr.out 简单对比
时间限制:0.5 s 内存限制:128 MB
【题目描述】
,对 1000000007 取模。F0=0,F1=1,F2=1
【输入格式】
一行一个整数 N
【输出格式】
一行一个整数 Ans
【样例输入】
4
【样例输出】
15
【数据范围】
1≤ N ≤1015
/*
矩阵乘法.n
定理:∑f[i]^2=f[n]*f[n+1]. i=1
Codevs3969的n<=10^50000直接弃疗了.
(20W遍快速幂 字符串处理是O(L)的然后就T了。。。
这个定理证明的话就是网上那个著名的
与斐波那契相关的图.
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod 1000000007
#define LL long long
using namespace std;
char ch[50010];
int n[50010];
LL ans[3][3],b[3][3],c[3][3],tot,l;
bool check()
{for(int i=1;i<=l;i++) if(n[i]) return true;return false;
}
void Div()
{for(int i=l;i>=1;i--){n[i-1]+=10*(n[i]%2);n[i]/=2;}while(!n[l]) l--;
}
void mi()
{while(check()){if(n[1]&1){for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)for(int k=1;k<=2;k++)c[i][j]=(c[i][j]+ans[i][k]*b[k][j]%mod)%mod;for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)ans[i][j]=c[i][j],c[i][j]=0;}for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)for(int k=1;k<=2;k++)c[i][j]=(c[i][j]+b[i][k]*b[k][j]%mod)%mod;for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)b[i][j]=c[i][j],c[i][j]=0;Div();}
}
void slove()
{ans[1][1]=1,ans[1][2]=0;b[1][1]=b[1][2]=b[2][1]=1;mi();tot=(ans[1][1]%mod*ans[1][2]%mod)%mod;
}
int main()
{freopen("fibsqr.in","r",stdin);freopen("fibsqr.out","w",stdout);cin>>ch+1;l=strlen(ch+1);for(int i=1;i<=l;i++) n[i]=ch[l-i+1]-48;slove();cout<<tot;return 0;
}
这篇关于Cogs 1708. 斐波那契平方和(矩阵乘法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!