题目链接:
http://www.51nod.com/Challenge/Problem.html#problemId=1242
1242 斐波那契数列的第N项
斐波那契数列的定义如下:
F(0) = 0
F(1) = 1
F(n) = F(n - 1) + F(n - 2) (n >= 2)
(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...)
给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可。
收起
输入
输入1个数n(1 <= n <= 10^18)。输出
输出F(n) % 1000000009的结果。输入样例
11输出样例
89
矩阵快速幂模板整理
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define pppp cout<<endl;
#define EPS 1e-8
#define LL long long
#define ULL unsigned long long //1844674407370955161
#define INT_INF 0x3f3f3f3f //1061109567
#define LL_INF 0x3f3f3f3f3f3f3f3f //4557430888798830399
// ios::sync_with_stdio(false);
// 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之类的一起使用了。
const int dr[]={0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1};
inline int read()//输入外挂
{
int ret=0, flag=0;
char ch;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
ret = ch - '0';
while((ch=getchar())>='0'&&ch<='9')
ret=ret*10+(ch-'0');
return flag ? -ret : ret;
}
LL l,r,k;
LL mod=1000000009;
bool Find(LL mid)
{
if(r/mid-(l-1)/mid >= k)
return true;
return false;
}
struct node
{
LL n,m,a[7][7];
node()
{
memset(a,0,sizeof(a));
}
};
node mul(node aa, node bb, LL n, LL m, LL k)
{
node cc;
cc.n=n;
cc.m=k;
for(int i=0;i<n;i++)
for(int j=0;j<k;j++)
for(int k=0;k<m;k++)
cc.a[i][j]=(cc.a[i][j]+aa.a[i][k]*bb.a[k][j]%mod)%mod;
return cc;
}
node power(node a, LL m)
{
node d;
d.n=d.m=a.n;
for(int i=0;i<d.n;++i)
d.a[i][i]=1;
while(m)
{
if(m&1)
d=mul(d,a,d.n,d.m,a.m);
m>>=1;
a=mul(a,a,a.n,a.n,a.n);
}
return d;
}
int main()
{
LL maxx;
cin>>maxx;
if(maxx<=2)//表示斐波那契的前两项
printf("%lld\n",1LL%mod);
else
{
node x;//系数矩阵
x.n=2;
x.m=2;
x.a[0][0]=1;
x.a[0][1]=1;
x.a[1][0]=1;
x.a[1][1]=0;
node tmp;//初始值矩阵
tmp.n=2;
tmp.m=1;
tmp.a[0][0]=1;
tmp.a[1][0]=1;
node ans=power(x,maxx-2);//计算系数
ans=mul(ans,tmp,ans.n,ans.m,tmp.m);
printf("%lld\n",ans.a[0][0]);
}
return 0;
}