历年真题斐波那契数列logn做法
Posted awcxv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了历年真题斐波那契数列logn做法相关的知识,希望对你有一定的参考价值。
描述
【题解】
用矩阵乘法加速递推
[0 1]
[1 1]
- [f[n-1]]
[f[n-2]]
=
[f[n-1]]
[f[n]]
求A矩阵的n-2次幂然后再乘B矩阵。
结果矩阵中的第二行第一列就是f[n]的结果了
【代码】
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int N = 100;
const long long MOD = 1e9+7;
const int G = 2;
struct abc
ll v[G+10][G+10];
void print()
for (int i = 1;i <= G;i++)
for (int j = 1;j <= G;j++)
printf("%I64d ",v[i][j]);
puts("");
puts("");
void E()
memset(v,0,sizeof v);
for (int i = 1;i <= G;i++) v[i][i]=1;
void O()
memset(v,0,sizeof v);
abc operator * (const abc b) const
abc temp;temp.O();
for (int i = 1;i <= G;i++)
for (int j = 1;j <= G;j++)
ll sum = 0;
for (int k = 1;k<= G;k++)
sum=(sum+v[i][k]*b.v[k][j])%MOD;
temp.v[i][j] = sum;
return temp;
abc operator ^(int n)const
abc x;x.E();
abc y;memcpy(y.v,v,sizeof(v));
while (n>0)
if (n&1) x=x*y;
y = y*y;
n/=2;
return x;
;
abc a,b;
int n;
int main()
scanf("%d",&n);
a.O();
a.v[1][1] = 0;a.v[1][2] = 1;
a.v[2][1] = 1;a.v[2][2] = 1;
b.O();
b.v[1][1] = 1;b.v[2][1] = 1;
if (n<=2)
printf("%d\n",1);
else
a = a^(n-2);
a = a*b;
printf("%I64d\n",a.v[2][1]);
return 0;
以上是关于历年真题斐波那契数列logn做法的主要内容,如果未能解决你的问题,请参考以下文章