1 <= n <= 100000000000000
数据大了会超时?开玩笑,2^3 log n这么小的数量级,秒秒钟跑完,重载运算符跑一下就好了,思路和斐波拉契1一样。
构造一个T矩阵,自乘n-2次,再和初始矩阵相乘,取mat[1][1]就好了。
注意因为数据大了,有可能乘起来爆int ,因为两个数都很接近mod的话,乘起来是爆int的,改用long long
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const LL maxn=5;
LL n;
const LL M=1000000007;
struct Mat
{
LL mat[maxn][maxn];
};
Mat operator*(Mat a,Mat b)
{
Mat c;
memset(c.mat,0,sizeof(c.mat));
for(LL k=1;k<=2;k++)
{
for(LL i=1;i<=2;i++)
{
for(LL j=1;j<=2;j++)
{
c.mat[i][j]+=(a.mat[i][k]%M*b.mat[k][j]%M);
c.mat[i][j]%=M;
}
}
}
return c;
}
Mat operator ^(Mat a,LL k)
{
Mat c;
memset(c.mat,0,sizeof(c.mat));
for(LL i=1;i<=2;i++)
{
for(LL j=1;j<=2;j++)c.mat[i][j]=(i==j);
}
for(;k;k>>=1)
{
if(k&1)c=c*a;
a=a*a;
}
return c;
}
int main()
{
freopen("2.out","w",stdout);
while(scanf("%lld",&n)!=EOF)
{
if(n<3)printf("1\n");
else
{
Mat f,g;
memset(f.mat,0,sizeof(f.mat));
f.mat[1][1]=f.mat[1][2]=f.mat[2][1]=1;
g=f^(n-2);
f.mat[1][2]=0;
g=g*f;
printf("%lld\n",g.mat[1][1]);
}
}
return 0;
}