本来以为很难的,但仔细想想和普通快速幂好像写法没什么区别尽管等会代码由于我太蒟蒻加暴力没写循环直接全部赋值,难点在于构造矩阵,这个题还挺明显的但自己还不是想不到。然后就是一般的快速幂n%2==1就乘,不是就把a数组翻倍。附上很丑的代码:
#include<stdio.h>
#include<stdlib.h>
long long qmpow(long long n)
{
long long a[3][3]={{0,0,0},
{0,1,1},
{0,1,0}},
ans[3][3]={{0,0,0},
{0,0,0},
{0,0,0}},
tmp[3][3]={0};
int i,j,flag=0;
while(n!=0)
{
if(n%2==1)
{
if(flag==0)
{
ans[1][1]=a[1][1];ans[1][2]=a[1][2];ans[2][1]=a[2][1];a[2][2]=a[2][2];
flag=1;
}
else
{
tmp[1][1]=ans[1][1]*a[1][1]+ans[1][2]*a[2][1];
tmp[1][2]=ans[1][1]*a[1][2]+ans[1][2]*a[2][2];
tmp[2][1]=ans[2][1]*a[1][1]+ans[2][2]*a[2][1];
tmp[2][2]=ans[2][1]*a[1][2]+ans[2][2]*a[2][2];
ans[1][2]=tmp[1][2];
ans[2][1]=tmp[2][1];
ans[2][2]=tmp[2][2];
ans[1][1]=tmp[1][1];
}
}
tmp[1][1]=a[1][1]*a[1][1]+a[1][2]*a[2][1];
tmp[1][2]=a[1][1]*a[1][2]+a[1][2]*a[2][2];
tmp[2][1]=a[2][1]*a[1][1]+a[2][2]*a[2][1];
tmp[2][2]=a[2][1]*a[1][2]+a[2][2]*a[2][2];
a[1][2]=tmp[1][2];
a[2][1]=tmp[2][1];
a[2][2]=tmp[2][2];
a[1][1]=tmp[1][1];
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
{
a[i][j]%=1000000007;
tmp[i][j]%=1000000007;
ans[i][j]%=1000000007;
}
n=n/2;
}
printf("%lld",(ans[1][1]+ans[1][2])%1000000007);
return 0;
}
int main()
{
long long n;
scanf("%lld",&n);
if(n==1||n==2)
{
printf("1");
return 0;
}
qmpow(n-2);
return 0;
}