为什么要演奏春日影
先挂上题目传送门吧。
题目大意
输入 \(n,d,m\),计算 \(\frac{f_{nd}}{f_d} \bmod m\)。
解题思路
首先,我们需要知道一个引理:\(f_{x+y}=f_{x+1}f_y + f_xf_{y-1}\)。
可以用数学归纳法证明,对于 \(b=0\) 或者 \(b=1\),该式显然成立。如果对于 \(b=k\) 和 \(b=k-1\) 等式成立,那么就有:
\[\begin{cases}
f_{a+k}=f_{a+1}f_k + f_a f_{k-1}\\
f_{a+k-1}=f_{a+1}f_{k-1}+f_a f_{k-2}
\end{cases}
\]
将两式相加,就有 \(f_{a+k+1}=f_{a+1}f_{k+1}+f_{a}f_{k}\),也就是说,对于 \(b=k+1\) 等式也成立,归纳完成。
应用该定理就可以得到:
\[f_{kd}=f_{d+1}f_{(k-1)d}+f_df_{(k-1)d-1}\\
f_{kd-1}=f_{d}f_{(k-1)d}+f_{d-1}f_{(k-1)d-1}
\]
我们令 \(g_k=\frac{f_{kd}}{f_d},h_k=f_{kd-1}\),那么第一个式子就变成了:
\[f_dg_k=f_{d+1}g_{k-1}f_d+f_dh_{k-1}
\]
两边同时除以 \(f_d\) 就有:
\[g_k=f_{d+1}g_{k-1}+h_{k-1}
\]
再观察第二个式子:
\[h_k={f_d}^2g_{k-1}+f_{d-1}h_{k-1}
\]
我们可以先用计算出 \(f_{d-1},{f_d}^2,f_{d+1}\) 作为矩阵快速幂的参数后用矩阵快速幂计算 \(g_k\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,n,d,m;
struct Matrix
{
int a[2][2];
Matrix(){a[0][0]=a[1][0]=a[0][1]=a[1][1]=0;}
Matrix operator * (const Matrix &x) const
{
Matrix res;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
res.a[i][j]=(res.a[i][j]+a[i][k]*x.a[k][j])%m;
}
}
return res;
}
};
Matrix qpow(Matrix a,int b)
{
if(b==0)
{
Matrix res;
res.a[0][0]=res.a[1][1]=1;
return res;
}
if(b==1) return a;
if(b==2) return a*a;
Matrix res=a;
b--;
while(b)
{
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
signed main()
{
cin>>t;
while(t--)
{
cin>>n>>d>>m;
Matrix base,sec_base,thd_base,fth_base;
fth_base.a[0][0]=thd_base.a[0][1]=sec_base.a[0][0]=base.a[0][0]=base.a[0][1]=base.a[1][0]=1;
Matrix ans1=qpow(base,d-1)*sec_base;
thd_base.a[0][0]=(ans1.a[0][0]+ans1.a[1][0])%m;
thd_base.a[1][0]=(ans1.a[0][0]*ans1.a[0][0])%m;
thd_base.a[1][1]=ans1.a[1][0];
fth_base.a[1][0]=ans1.a[1][0];
Matrix ans2=qpow(thd_base,n-1)*fth_base;
cout<<ans2.a[0][0]<<'\n';
}
return 0;
}

浙公网安备 33010602011771号