洛谷P1962 斐波那契数列
Posted lonlyn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1962 斐波那契数列相关的知识,希望对你有一定的参考价值。
题目:https://www.luogu.org/problemnew/show/1962
题目背景
大家都知道,斐波那契数列是满足如下性质的一个数列:
• f(1) = 1
• f(2) = 1
• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)
题目描述
请你求出 f(n) mod 1000000007 的值。
输入输出格式
输入格式:
·第 1 行:一个整数 n
输出格式:
第 1 行: f(n) mod 1000000007 的值
输入输出样例
说明
对于 60% 的数据: n ≤ 92
对于 100% 的数据: n在long long(INT64)范围内。
解析
给了60分的暴力分,美滋滋= ̄ω ̄=
那么剩下的40分怎么办Σ( ° △ °|||)︴
别告诉我你要打一个辣么大的表( ﹁ ﹁ ) ~→
好吧,这就需要一个重要的知识点叫做矩阵乘法。
矩阵乘法不会的,请咨询度娘吧23333333333333.
矩阵乘法满足结合律哦。
我们可以把状态转移方程转化成矩阵相乘,然后,
中间乘的矩阵都是一样的哦。
那么,想到什么了吗(⊙ω⊙)
对啦,就是快速幂啦(∩_∩)
矩阵快速幂与快速幂的做法很相似哦!相信大佬们一定会的(~ ̄▽ ̄)~
好了,蒟蒻的代码如下了:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define ll long long 8 #define mod 1000000007 9 struct submix{ 10 ll a[5][5]; 11 }; 12 submix operator * (submix x,submix y){ 13 submix res; 14 memset(res.a,0,sizeof(res.a)); 15 for (ll k=1;k<=2;++k){ 16 for (ll i=1;i<=2;++i){ 17 for (ll j=1;j<=2;++j){ 18 res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mod; 19 } 20 } 21 } 22 return res; 23 } 24 ll f[1010]; 25 ll n; 26 submix ori,enm; 27 submix ksm(submix x,ll k){ 28 submix res=ori; 29 while (k){ 30 if (k&1){ 31 res=res*x; 32 } 33 x=x*x; 34 k=k/2; 35 } 36 return res; 37 } 38 int main(){ 39 cin>>n; 40 if (n==1){ 41 cout<<"1"; 42 return 0; 43 } 44 if (n==2){ 45 cout<<"1"; 46 return 0; 47 } 48 ori.a[1][1]=1; 49 ori.a[1][2]=1; 50 ori.a[2][1]=1; 51 ori.a[2][2]=0; 52 enm=ksm(ori,n-3); 53 /*cout<<enm.a[1][1]<<endl; 54 cout<<enm.a[1][2]<<endl; 55 cout<<enm.a[2][1]<<endl; 56 cout<<enm.a[2][2]<<endl;*/ 57 cout<<(enm.a[1][1]+enm.a[2][1])%mod; 58 return 0; 59 }
注释语句是我检验输出的,就无视掉吧233
以上是关于洛谷P1962 斐波那契数列的主要内容,如果未能解决你的问题,请参考以下文章