斐波那契循环节
Posted cjoiershiina-mashiro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斐波那契循环节相关的知识,希望对你有一定的参考价值。
斐波那契循环节
从一道题引出一个算法:斐波那契数列
这道题并没有什么花里胡哨的条件,就是很简单的计算\(F(n)\ mod\ p\)。
但是这题的\(n\)达到了\(10^30000000\)级别,很显然不能直接用矩阵快速幂做。
因此我们要引入一个概念:斐波那契循环节。
显而易见的是通过看题解我们知道,斐波那契数列在模一个数时会出现循环,而这个周期的长度就称为斐波那契循环节。
所以我们只需要求出斐波那契循环节\(m\),然后用矩阵快速幂计算\(F(n\ mod\ m)\ mod\ p\)就行了。
下面将会介绍如何计算斐波那契循环节。
(因为这只是介绍文并非论文,难免有不严谨之处,敬请谅解。本文以通俗易懂为前提,夹有较为详细的证明。)
参考自一篇全英文的paperThe Period of the Fibonacci Sequence Modulo j
\(Tips:\)
\(1.\)本文的数学推导具有一定难度,部分知识涉及到了高等代数和初等数论,不知道的东西可以上网查,如果实在不懂可以暂时跳过,因为这并不会影响到阅读其他部分。
\(2.\)如果不想看证明过程,可以直接跳到第五部分看结论。
\(1.\)前置知识
二次剩余
直接看我的另一篇博客吧。二次剩余
域
有一个非空集合\(G\),和在\(G\)上的一个二元运算\(\cdot:G\times G\mapsto G\)。
(一般我们叫这个运算乘法,其运算结果为积)
它们构成了一个代数系统\(\G,\cdot\\),这个代数系统满足:
\(1.\)封闭性:\(\forall a,b\in G,a\cdot b\in G\)。
\(2.\)结合律:\(\forall a,b,c\in G,(a\cdot b)\cdot c=a\cdot(b\cdot c)\)。
那么我们将其称为半群。
如果这个半群还满足
\(3.\)单位元:\(\exists e\in G,\forall a\in G,e\cdot a=a\cdot e=a\)。这个\(e\)称作单位元,或者称作\(1\)。(\(a^0=1\))
\(4.\)逆元:\(\forall a\in G,\exists b\in G,a\cdot b=b\cdot a=e\)。这个\(b\)称作\(a\)的逆元,记做\(a^-1\)。(逆元具有唯一性)
那么我们将其称为群。
如果这个群还满足
\(5.\)交换律:\(\forall a,b\in G,a\cdot b=b\cdot a\)。
那么我们称这个群为交换群或阿贝尔群。
在阿贝尔群中这个二元运算经常被称作加法,其运算结果为和,这个运算记做\(+\)。
此时该群的单位元经常被称作零元,记作\(0\)。\(a\)逆元的逆元经常被记作\(-a\)。
(这些东西可以联想实数的加法和乘法)
设\(\G,+,\cdot\\)是一个代数系统(\(G\)是非空集合,\(+\)和\(\cdot\)为二元运算即加法和乘法),若
\(1.\G,+\\)是一个交换群。
\(2.\G,\cdot\\)是一个半群。
\(3.\)分配率:\(\forall a,b,c\in G,a\cdot(b+c)=(a\cdot b)+(a\cdot c),(a+b)\cdot c=(a\cdot c)+(b\cdot c)\)。
那么我们将其称为环。
如果这个环满足
\(4.\G\setminus\0\,\cdot\\)是一个交换群。
那么我们将其称为域。(实际上第四条性质中把\(0\)去掉就只是因为在域中\(0\)不具有乘法逆元)
特征方程
百度百科特征方程,包会。特征方程
\(2.\)定义
斐波那契数列
\[ \forall n\in\mathbb N_ +,F_n+1=F_n+F_n-1(F_0=0,F_1=1) \]
令\(\phi=\frac1+\sqrt52,\overline\phi=\frac1-\sqrt52\),易知有\(\phi^2=\phi+1\)与\(\overline\phi^2=\overline\phi+1\)。
实际上这就是斐波那契数列的特征方程\(x^2=x+1\)的两实数根。
并且由此我们可以推出斐波那契数列的通项公式
\[ F_n=\frac1\sqrt5(\phi^n-\overline\phi^n) \]
斐波那契循环节
模\(p\)意义下的斐波那契数列\(F_n(mod\ p)\)的循环节\(m\)是使得\(F_m\equiv0(mod\ p)\bigwedge F_m+1\equiv1(mod\ p)\)的最小正整数\(m\)。
易知\(m|k\Leftrightarrow F_k\equiv0(mod\ p),F_k+1\equiv1(mod\ p)\)。
\(3.\)第一部分证明
我们需要先证明一些引理。(或者说是与结论直接关系不大的定理)
引理\(1\)
设\(p\)为素数,\(n\)为正整数,若\(a\equiv1(mod\ p)\),则\(a^p^n\equiv1(mod\ p^n+1)\)。
证:
我们使用数学归纳法。
不妨设\(a=rp+1(r\in\mathbb Z)\)。
运用二项式定理,
\[
a^p\equiv(rp+1)^p\equiv1+\sum\limits_i=1^p\left(_i^p\right)(rp)^i\equiv1(mod\ p^2)
\]
因此当\(n=1\)时引理成立。
假设\(n=m\)时定理成立,即有\(a^p^m\equiv1(mod\ p^m+1)\)。
不妨设\(a^p^m=1+sp^m+1(s\in\mathbb Z)\)。
同样运用二项式定理,
\[
a^p^m+1=(a^p^m)^p=(1+sp^m+1)^p=1+\sum\limits_i=1^p\left(_i^p\right)(sp^m+1)^i\equiv1(mod\ p^m+2)
\]
因此当\(n=m\)成立时,\(n=m+1\)也成立。
引理\(1\)得证。
推论\(1\)
设\(p\)为素数,\(k\)为正整数,\(m\)为\(F_n(mod\ p)\)的循环节,有\(\phi^mp^k-1\equiv\overline\phi^mp^k-1\equiv1(mod\ p^k)\)
证:
\[
\because F_m\equiv\frac\phi^m-\overline\phi^m\sqrt5\equiv0(mod\ p)
\]
\[ \therefore\phi^m\equiv\overline\phi^m(mod\ p) \]
我们知道有
\[ F_m=F_m+1-F_1=\frac\phi(\phi^m-1)-\overline\phi(\overline\phi^m-1)\sqrt5 \]
用\(\phi^m\)替换\(\overline\phi^m\)得到
\[ F_m\equiv\frac(\phi^m-1)(\phi-\overline\phi)\sqrt5\equiv(\phi^m-1)F_1\equiv\phi^m-1\equiv0(mod\ p) \]
\[ \therefore\phi^m\equiv\overline\phi^m\equiv1(mod\ p) \]
运用引理\(1\),
\[ \phi^mp^k-1\equiv\overline\phi^mp^k-1\equiv1(mod\ p^k) \]
推论\(1\)得证。
引理\(2\)
设\(p\)为\(5\)以外的素数,那么\((\frac5p)=1\Leftrightarrow p\equiv\pm1(mod\ 5),(\frac5p)=-1\Leftrightarrow p\equiv\pm2(mod\ 5)\)
(勒让德符号,前置知识中有讲解)
证:
运用二次互反律,
\[
(\frac5p)(\frac p5)=(-1)^(\frac5-12)(\fracp-12)=((-1)^\fracp-12)^2=1
\]
运用勒让德符号的定义式,
\[
(\frac5p)=(\frac p5)\equiv p^2(mod\ 5)
\]
然后把\(1\)到\(4\)代进去算就可以证明了。(实际上是懒得打了)
\(4.\)第二部分证明
现在进入中心环节的证明。
这一部分的定理与斐波那契循环节有着更强的联系,实际上将求斐波那契循环节一点点分解然后解决。
定理\(1\)
设\(P=\prod\limits_i=1^sp_i^k_i\),\(m_i\)为\(F_n(mod\ p_i^k_i)\)的循环节,\(M\)为\(F_n(mod\ P)\)的循环节,则\(M=lcm(m_1,\cdots,m_s)\)。
证:
\[ \because F_M\equiv0(mod\ P) \]
\[ \therefore F_M\equiv0(mod\ p_i^k_i) \]
\[ \therefore\forall i\le s,m_i|M \]
\[ \therefore M=lcm(m_1,\cdots,m_s) \]
定理\(1\)得证。
定理\(2\)
设\(p\)为素数,\(m\)是\(F_n(mod\ p)\)的循环节,\(M\)是\(F_n(mod\ p^k)\)的循环节,则\(M| mp^k-1\)。
证:
由推论\(1\)我们有
\[
\phi^mp^k-1\equiv\overline\phi^mp^k-1\equiv1(mod\ p^k)
\]
\[ \therefore F_mp^k-1\equiv\frac\phi^mp^k-1-\overline\phi^mp^k-1\sqrt5\equiv0(mod\ p^k) \]
\[ \therefore F_mp^k-1+1\equiv\frac\phi^mp^k-1+1-\overline\phi^mp^k-1+1\sqrt5\equiv\frac\phi-\overline\phi\sqrt5\equiv1(mod\ p^k) \]
\[ \therefore M|mp^k-1 \]
定理\(2\)得证。
定理\(3\)
设\(p\)为素数,\(m\)为\(F_n(mod\ p)\)的循环节,若\(p\equiv\pm1(mod\ 5)\),则\(m| p-1\)
证:
由引理\(2\)知\(5\)是\(p\)的二次剩余,所以可以直接开方(\(\sqrt5\)在模\(p\)的域\(\mathbbF_p\)中)。
运用费马小定理,
\[
\phi^p-1\equiv\overline\phi^p-1\equiv 1(mod\ p)
\]
\[ \therefore F_p-1\equiv\frac\phi^p-1-\overline\phi^p-1\sqrt5\equiv0(mod\ p),F_p\equiv\frac\phi^p-\overline\phi^p\sqrt5\equiv\frac\phi-\overline\phi\sqrt5\equiv1(mod\ p) \]
\[ \therefore m|p-1 \]
定理\(3\)得证。
定理\(4\)
设\(p\)为素数,\(m\)为\(F_n(mod\ p)\)的循环节,若\(p\equiv\pm2(mod\ 5)\),则\(m|2p+2\bigwedge 2\nmid\frac2p+2m\)
证:
由引理2知\(5\)不是是\(p\)的二次剩余,因此不可以直接开方(\(\sqrt5\)在不在模\(p\)的域\(\mathbbF_p\)中)。
所以我们定义\(\mathbbF_p(\sqrt5)=\a+b\sqrt5|a,b\in\mathbbF_p\\)。
这里可以理解为类似于从实数域扩展到复数域,然后我们可以证明它满足域的特征。
(证明在附录中)
利用二项式定理,我们有
\[
(a+b)^p\equiv a^p+b^p(mod\ p)
\]
\[ \therefore\phi^p\equiv(\frac12+\frac\sqrt52)^p\equiv(\frac12)^p+(\frac\sqrt52)^p\equiv(\frac12)^p(1+\sqrt5^p)\equiv\frac12(1+5^\fracp-12\sqrt5)\equiv\frac12(1-\sqrt5)\equiv\overline\phi \]
同理,我们可以得到\(\overline\phi^p=\phi\)。
因此我们有
\[ F_p\equiv\frac\phi^p-\overline\phi^p\sqrt5\equiv\frac\overline\phi-\phi\sqrt5\equiv p-1(mod\ p) \]
\[ F_p+1\equiv\frac\phi^p+1-\overline\phi^p+1\sqrt5\equiv\frac\overline\phi\phi-\phi\overline\phi\sqrt5\equiv0(mod\ p) \]
\[ F_p+2\equiv F_p+F_p+1\equiv p-1(mod\ p) \]
\[ \therefore m\nmid p+1 \]
又有
\[ F_2p+1\equiv\frac\phi^2p+1-\overline\phi^2p+1\sqrt5\equiv\frac\overline\phi^2\phi-\phi^2\overline\phi\sqrt5\equiv\frac\phi\overline\phi(\overline\phi-\phi)\sqrt5\equiv1(mod\ p) \]
\[ F_2p+2\equiv\frac\phi^2p+2-\overline\phi^2p+2\sqrt5\equiv\frac\overline\phi^2\phi^2-\phi^2\overline\phi^2\sqrt5\equiv0(mod\ p) \]
\[ F_2p+3\equiv F_2p+1+F_2p+2\equiv1(mod\ p) \]
\[ \therefore m| 2p+2 \]
\[ \therefore 2\nmid\frac2p+2m \]
综上,
\[
m|2p+2\bigwedge 2\nmid\frac2p+2m
\]
定理\(4\)得证。
\(5.\)结论
实际上计算斐波那契循环节的方式已经在第四部分完全给出,下面做一下总结。
对于\(F_n(mod\ P)\)求其循环节\(M\)总共分\(3\)步:
\(step1\)
由定理1,分解质因数\(P=\prod\limits_i=1^sp_i^k_i\),求\(F_n(mod\ p_i^k_i)\)的循环节\(M_i\),然后取\(M=lcm(M_1,\cdots,M_s)\)
\(step2\)
现在我们将问题转化成了求\(F_n(mod\ p_i^k_i)\)的循环节\(M_i\)。
由定理2,\(F_n(mod\ p_i^k_i)\)的循环节\(M_i\)是\(p_i^k_i-1\)乘\(F_n(mod\ p_i)\)的循环节\(m_i\)的积\(m_ip_i^k_i-1\)的某一因数。
一个个检查因数会很麻烦,直接取这个\(m_ip_i^k_i-1\)也没有任何问题。因为我们是为了快速计算斐波那契数列的某个值,而\(m_ip_i^k_i-1\)是\(M_i\)一个倍数,最后得到的"循环节"\(\overline M=lcm(m_1p_1^k_1-1,\cdots,m_sp_s^k_s-1)\)也就会相应地变成正确的循环节\(M\)的倍数。但是\(\overline M\)一定是斐波那契数列循环的周期之一。(类似于三角函数最小正周期与周期的关系)。而且这个值也不会很大\((long\ long\)范围内\()\),对其取模然后跑矩阵快速幂完全没有问题。
\(step3\)
对于每个\(p_i\),如果\(p_i\le5\),直接打表:\(2\)的最小循环节是\(3,3\)的最小循环节是\(8,5\)的最小循环节是\(20\)。(这个都手算即可)
若\(p_i\equiv\pm1(mod\ 5)\),则\(m_i\)是\(p_i-1\)的某一因数,理由同上,直接取本身即可。
若\(p_i\equiv\pm2(mod\ 5)\),则\(m_i\)是\(2p+2\)的某一因数且\(2\nmid\frac2p+2m\),直接取本身亦可。
\(6.\)附录
关于上面那个不太重要的证明,这里进行补充。
\(\mathbbF_p(\sqrt5)=\a+b\sqrt5|a,b\in\mathbbF_p\\)是一个域的证明
首先我们了解一下\(\mathbb F_p\)
设集合\(G=\0,1,\cdots,p-1\\)(\(p\)是素数),并对其定义模\(p\)意义下的加法\(+\)和乘法\(\cdot\),易证其是一个域,记为\(\mathbb F_p\)。
其零元为\(0\),单位元为\(1\),\(a\)的加法逆元为\(p-1-a\),除\(0\)以外的数的乘法逆元一定存在。
然后开始证明
首先证明\(\mathbb F_p(\sqrt5)\)对于加法是一个交换群。
封闭性:
任取
\[
a,A\in\mathbb F_p(\sqrt5),a=b+c\sqrt5,A=B+C\sqrt5
\]
易知
\[
b,B,c,C\in\mathbb F_p
\]
于是有
\[
b+B,c+C\in\mathbb F_p
\]
则
\[
a+A=(b+B)+(c+C)\sqrt5\in\mathbb F_p(\sqrt5)
\]
结合律:仿照证明封闭性易证不难。
零元:易知\(0+0\sqrt5\)是零元。
逆元:\(a+b\sqrt5\)的逆元为\((p-1-a)+(p-1-b)\sqrt5\)。
交换律:仿照证明封闭性易证不难。
所以\(\mathbb F_p(\sqrt5)\)对于加法是一个交换群。
然后我们证明\(\mathbb F_p(\sqrt5)\)去掉零元之后对于乘法是一个交换群。
封闭性:仿照证明对于加法有封闭性易证不难。
结合律:仿照证明对于加法有结合律易证不难。
零元:易知\(1+0\sqrt5\)是零元。
逆元:这个是最不好做的,对于\(A=a+b\sqrt5\),我们先取一个\(B=a-b\sqrt5\),这两个乘起来是一个整数\(a^2-5b^2\),显然这个数不为\(0\),我们再把\(B\)的两个系数\(a\)和\(b\)都除以这个数就行了。
交换律:仿照证明对于加法有交换律易证不难。
所以\(\mathbb F_p(\sqrt5)\)去掉零元后对于乘法是一个交换群。
因此\(\mathbb F_p(\sqrt5)\)是一个域。
(几乎完全一样的过程要写十遍我人都傻了,自己证一下吧,都看到这了相信你一定能证明的)
\(7.\)代码
注意特判模数为\(1\)的情况。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e4,S=30000001;
char s[S];
LL pi[N],k[N],P;
inline LL gcd(register LL n,register LL m)while(m^=n^=m^=n%=m); return n;
inline LL lcm(register LL n,register LL m)return n/gcd(n,m)*m;
struct matrix
LL a[3][3];
matrix()memset(a,0,sizeof(a));
matrix operator*(matrix x)
matrix s;
for(register int i=1;i<=2;i++) for(register int j=1;j<=2;j++) for(register int k=1;k<=2;k++) s.a[i][j]=(s.a[i][j]+a[i][k]*x.a[k][j])%P;
return s;
matrix operator^(register LL k)
matrix s=*this,e;
e.a[1][1]=e.a[2][2]=1;
for(;k;k>>=1,s=s*s) if(k&1) e=e*s;
return e;
;
inline int power(register LL n)
matrix a,ans;
a.a[1][1]=a.a[1][2]=a.a[2][1]=1,a.a[2][2]=0;
ans=a^n;
return ans.a[1][2];
inline LL Get(register LL p)
register int s=sqrt(p),tot=0;
for(register int i=2;i<=s;++i)
if(!(p%i))
pi[++tot]=i,k[tot]=1;
while(!(p%i)) p/=i,k[tot]*=i;
for(register int i=1;i<=tot;++i) k[i]/=pi[i];
if(p!=1) k[++tot]=1,pi[tot]=p;
for(register int i=1;i<=tot;++i)
if(pi[i]==2) k[i]*=3;
else if(pi[i]==3) k[i]*=5;
else if(pi[i]==5) k[i]*=20;
else if(pi[i]%5==1||pi[i]%5==4) k[i]*=pi[i]-1;
else k[i]*=(pi[i]+1)<<1;
register LL ans=k[1];
for(register int i=2;i<=tot;++i) ans=lcm(ans,k[i]);
return ans;
int main()
register int len;
register LL m,n=0;
scanf("%s%lld",s+1,&P),len=strlen(s+1);
if(P==1) return cout<<0,0;
m=Get(P);
for(register int i=1;i<=len;++i) n=((n<<3)+(n<<1)+(s[i]^48))%m;
if(!n) return cout<<0,0;
if(n==1) return cout<<1,0;
return cout<<power(n),0;
\(8.\)扩展
那个英文论文里面已经讲了另外一个数列\(Lucas\)数列,可以去看看练练手。
实际上大多数二阶线性递推数列都可以这样做,具体方法就是把\(\phi\)和\(\overline\phi\)换成其特征方程的两根,然后再各种部分相应修改即可。这里就不多讲了。留作读者自行练习
以上是关于斐波那契循环节的主要内容,如果未能解决你的问题,请参考以下文章