做这题本来想把状态矩阵乘上转移矩阵的(n-2)次幂然后输出f(0)的,结果答案不对。然后蒟蒻急中生智一顿乱改,把次数改成n-1,又把答案减去1,然后莫名其妙就A了?
。。。。。有没有佬解释一下为什么。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll n,f[2]={1,1},a[2][2]={{0,1},{1,1}},ans[2][2]={{1,0},{0,1}};
void gzksm(ll p)//矩阵快速幂
{
while(p)
{
if(p&1)
{
ll c[2][2]={0};
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
{
c[i][j]=(c[i][j]+(ans[i][k]*a[k][j])%mod)%mod;
}
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
ans[i][j]=c[i][j];
}
}
ll d[2][2]={0};
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
{
d[i][j]=(d[i][j]+(a[i][k]*a[k][j])%mod)%mod;
}
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
a[i][j]=d[i][j];
}
p>>=1;
}
}
int main()
{
cin>>n;
if(n<=2) cout<<1;
else
{
gzksm(n-1);//这里本来是n-2
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
f[i]=(f[i]+(f[j]*ans[j][i])%mod)%mod;
}
cout<<f[0]-1;//原来没有-1
}
return 0;
}