题意:
给你公式:
F1 = x, F2 = y;
Fi = F(i-1) + F(i+1);(其中i>=2)
题解:
好,我们来转换公式变成F(i+1)=F(i)-F(i-1),然后i各减去1,得F(i)=F(i-1)-F(i-2),然后就可以推出矩阵的关系了:
F(i)=1*F(i-1)-1*F(i-2);
F(i-1)=1*F(i-1)-0*F(i-2);
得:
然后二阶矩阵就可以通过矩阵快速幂算出n-2次之后的结果,a[0][0]*F2+a[0][1]*F1就可以过了。
#include<stdio.h>
#include<string.h>
#define LL long long int
const int MOD=1000000007;
struct node
{
LL m[2][2];
node()
{
memset(m,0,sizeof(m));
}
};
node cla(node a,node b)
{
node c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
if(a.m[i][k]&&b.m[k][j])//剪枝(添条件,设门槛),提高效率,有一个是0,相乘肯定是0
{
c.m[i][j]+=a.m[i][k]*b.m[k][j];
c.m[i][j]%=MOD;
}
return c;
}
LL POW(LL x,LL y,LL k)
{
node a,c;
for(int i=0;i<2;i++) c.m[i][i]=1;
a.m[0][0]=1,a.m[0][1]=-1;
a.m[1][0]=1,a.m[1][1]=0;
while(k)
{
if(k&1) c=cla(c,a);
a=cla(a,a);
k>>=1;
}
printf("%lld\n",(((y*c.m[0][0]+MOD)%MOD)+((x*c.m[0][1]+MOD)%MOD))%MOD);
}
int main()
{
LL x,y,n;
while(~scanf("%lld%lld%lld",&x,&y,&n))
{
if(n==1)
printf("%lld\n",(x+MOD)%MOD);//+MOD再模是为了保证你是负数的情况+MOD再模,就算是正数+MOD再模也一样。
else if(n==2)
printf("%lld\n",(y+MOD)%MOD);
else
POW(x,y,n-2);
}
}