51nod 1365 Fib(N) mod Fib(K)-题解

发布时间 2023-05-07 20:44:02作者: 6penny

51nod 1365 Fib(N) mod Fib(K)

个人评价:考一些奇奇怪怪的知识点呢

算法

矩阵快速幂、斐波那契公式

题面

\(F_n\%F_k\)的值,\(1\leq n,k\leq 1e18\)

问题分析

我一开始居然想着直接矩阵快速幂求出两个值算,我也是真的牛……

我们要知道这些斐波那契公式(考的真怪)

\[F_{-n}=(-1)^{n-1}F_n \]

\[F_n=F_kF_{n-k+1}+F_{k-1}F_{n-k} \]

\[F_{k-1}^2+F_{k-1}F_k-F_k^2=(-1)^k \]

问题求的是\(F_n \% F_k\)的值,所以我们考虑所有计算推导相等在模\(F_k\)下进行

开始娱乐地推式子了

\[\begin{aligned} F_n&=F_kF_{n-k+1}+F_{k-1}F_{n-k} \\ &=F_{k-1}F_{n-k}\\ &=F_{k-1}(F_kF_{n-2k+1}+F_{k-1}F_{n-2k})\\ &=F_{k-1}^2F_{n-2k}\\ \end{aligned} \]

所以可以得到\(F_n=F_{k-1}^{\lfloor\frac{n}{k}\rfloor}F_{n\%k}\)

看到最后一个公式,我们也在模\(F_k\)意义下推导

\[\begin{aligned} (-1)^k&=F_{k-1}^2+F_{k-1}F_k-F_k^2 \\ &=F_{k-1}^2\\ \end{aligned} \]

\(\lfloor\frac{n}{k}\rfloor=i,n\%k=j\) 考虑将这个带入到\(F_n\)的式子,然后进行分类讨论:

  1. 当i&1=0:\(F_n=(-1)^{k\times \frac{i}{2}}F_j\)
  2. 当i&1=1:\(F_n=F_{k-1}^iF_j=F_{k-1}^i(F_{k-1}F_{j-k}+F_kF_{j-k+1})=F_{k-1}^{i+1}F_{j-k}=(-1)^{\frac{i+1}{2}k+k-j-1}F_{k-j}\)

代码实现

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll p=1e9+7;
struct Matrix{
	ll x[10][10];
};
Matrix mul(Matrix a,Matrix b){
	Matrix res;
	memset(res.x,0,sizeof res.x);
	for(ll i=0;i<2;i++){
		for(ll j=0;j<2;j++){
			for(ll k=0;k<2;k++){
				res.x[i][j]=(res.x[i][j]+a.x[i][k]*b.x[k][j]%p)%p;
			}
		}
	}
	return res;
}
ll qpow(Matrix a,ll k){
	Matrix res;
	memset(res.x,0,sizeof res.x);
	for(ll i=0;i<2;i++)res.x[i][i]=1;
	while(k){
		if(k&1)res=mul(res,a);
		a=mul(a,a);
		k>>=1;
	}
	return res.x[0][0]%p;
}

void solve(){
	ll n,k;
	Matrix a;
	memset(a.x,0,sizeof a.x);
	a.x[0][0]=a.x[0][1]=a.x[1][0]=1;
	scanf("%lld%lld",&n,&k);
	ll i=n/k,j=n%k;
	ll ans=0,mod=qpow(a,k-1);
	if(i%2==0){
		if(j==k)ans=0;
		else ans=qpow(a,j-1);
		if(k%2==1)ans=-ans;
		if(ans<0)ans=(ans+mod);
		ans=(ans+p)%p;
	}else{
		if(j==0)ans=0;
		else ans=qpow(a,k-j-1);
		if((k-j-1)%2==1)ans=-ans;
		if(ans<0)ans=(ans+mod);
		ans=(ans+p)%p;
	}
	printf("%lld\n",(ans+p)%p);
}
int main(){
	ll T;
	scanf("%lld",&T);
	while(T--)solve();


	return 0;
}

总结

这个考的东西真的很奇怪,也算是我的积累问题吧,毕竟斐波那契我就只知道那两个通项公式,还是得多做点题