题意(原题):
求斐波那契数列第n项模10^9+7的值。n<=2^31-1
思路:
由于n很大,所以不能暴力。
考虑矩阵乘法。
[ 0 1 ] x [ 2 ] = [ 3 ]
[ 1 1 ] …[ 3 ] … [ 5 ]
那么把求出第一个矩阵的n-1次方后乘以[ 0 ]即可得出结果。
…………………………………………………………[ 1 ]
矩阵乘法的时候别忘记了模。
我不知道markdown怎么画矩阵,抱歉。
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define LL long long
#define GETMOD %1000000007
using namespace std;
struct node
{
int xcnt,ycnt;LL a[110][110];
node()
{
xcnt=ycnt=0;memset(a,0,sizeof(a));
}
void setxy(int x,int y)
{
xcnt=x;ycnt=y;
}
};
node dw(int x)
{
node ans;ans.setxy(x,x);
for(int i=1;i<=x;i++)ans.a[i][i]=1;
return ans;
}
node cf(node x,node y)
{
node ans;ans.setxy(x.xcnt,y.ycnt);
for(int i=1;i<=ans.xcnt;i++)
for(int j=1;j<=ans.ycnt;j++)
for(int k=1;k<=x.ycnt;k++)
ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]GETMOD)GETMOD;
return ans;
}
node power(node x,int k)
{
node ans=dw(x.xcnt);
while(k)
{
if(k&1)ans=cf(ans,x);
x=cf(x,x);
k/=2;
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
node opt;opt.setxy(2,2);opt.a[1][2]=1;opt.a[2][1]=1;opt.a[2][2]=1;
opt=power(opt,n-1);
node ans;ans.setxy(2,1);ans.a[2][1]=1;
ans=cf(opt,ans);
printf("%lld\n",ans.a[2][1]);
return 0;
}