P4000 斐波那契数列题解

· · 题解

P4000 斐波那契数列

题目就是要求 f_n \text{ mod } p 的值。如果尝试着用矩阵乘法,明显会T的很惨,因为 n\le 10^{30000000}

约定:题目中的 p 在下文记作 m,防止与泛指质数的字母 p 弄混淆。

计算斐波那契数列循环节

结论 1:斐波那契数列对 m 取模后必定是周期数列。

证明:考虑

(F_1,F_2),(F_2,F_3),(F_3,F_4),\cdots,(F_{p^2+1},F_{p^2+2})

m^2+1 组两个相邻的斐波那契数组成的数对。一个正整数模 m 只有 0,1,\cdots,m-1m 个结果,故一个数对中两个数模 m 共有 m^2 种情况,由抽屉原理可得上面 m^2+1 组数对必然至少两个是相同的。从而它们后面所生成的模意义下的斐波那契数列也是相同的。

从而存在 i,j(i<j),使得 F_i \equiv F_j 并且 F_{i+1} \equiv F_{j+1}。则数列的循环周期为 j-i+1(不一定是最小正周期),令其为 k。那么对于任意自然数 i,都有 F_i=F_{i+k}=F_{i+2k}=\cdots,即斐波那契数列对 m 取模后必然是周期数列。

皮萨诺周期(Pisano periods, OEIS A001175):模 m 意义下的斐波那契数列的最小正周期被称为皮萨诺周期。为了方便表示,将其记作 \text{Pi}_m

事实上,有 \text{Pi}_m \le 6m,当且仅当 m=2 \times 5^k (k \in \mathbb N) 时取等号。(我也不知道怎么证明,貌似对这道题有一点优化的作用,不过没有太大用处)

结论 2:若 a,b 互质,则 \text{Pi}_{ab}=\text{lcm}(\text{Pi}_a,\text{Pi}_b)

正确性显然。

Part 1. 当 m 为素数

我们知道斐波那契数列的通项公式

F_n=\frac{1}{\sqrt 5}\left(\left(\frac{1+\sqrt 5}{2}\right)^n-\left(\frac{1-\sqrt 5}{2}\right)^n\right)

由于里面有一个 \sqrt 5,所以我们得分类讨论。

结论 3:对于任意奇素数 p 使得 x^2\equiv 5 \pmod p 有非 0 解,则 p-1 是模 p 斐波那契数列的周期。即 \text{Pi}_p | p-1

证明:此时 \sqrt{5},\dfrac 12 在模 p 下都有意义。那么有

\begin{aligned} F_n&=\frac{1}{\sqrt 5}\left(\left(\frac{1+\sqrt 5}{2}\right)^n-\left(\frac{1-\sqrt 5}{2}\right)^n\right) \\ &\equiv \frac{1}{\sqrt 5}\left(\left(\frac{1+\sqrt{5}}{2}\right)^{n+\varphi(p)}-\left(\frac{1-\sqrt 5}{2}\right)^{n+\varphi(p)}\right) \\ &\equiv F_{n+p-1} \end{aligned}

即周期为 p-1

在代码编写当中,判断依据可以写 if(qpow(5,(p-1)/2,mod)==1)。当然,写 if(p%5==1||p%5==4) 是更好的选择。事实上,这种情况下 p \equiv 1,4 \pmod 5

下面给出证明:由 x^2 \equiv 5 \pmod p 存在非 0 解,则有 \left(\dfrac{5}{p}\right)=1,其中 \left(\dfrac{a}{p}\right) 是勒让德符号。由二次互反律(它的证明我不想写了,有亿点复杂,可以在网上搜)

\displaystyle\left(\frac{p}{q}\right)\left(\frac{q}{p}\right)=(-1)^{\frac{p-1}2\frac{q-1}2}

可以得到 \left(\dfrac{5}{p}\right)\left(\dfrac{p}{5}\right)=(-1)^{2\times\frac{p-1}2},即 \left(\dfrac p5\right)=1,也就是说方程 x^2 \equiv p \pmod 5 有非 0 解,即 p \equiv 1,4 \pmod 5

结论 4:对于任意奇素数 p 使得 x^2\equiv 5 \pmod p 无解,则 2p+2 是模 p 斐波那契数列的周期。即 \text{Pi}_p|2p+2

证明:此时 \sqrt{5} 在模 p 下无意义。即 5^{\frac{p-1}2} \equiv -1 \pmod p,也就是 \sqrt 5^{p-1} \equiv -1 \pmod p

对斐波那契数列通项公式进行二项式展开:

\begin{aligned} F_n&=\frac{1}{2^n\sqrt 5}\left(\sum\limits_{i=0}^n\dbinom{n}{i}\sqrt 5^i-\sum\limits_{i=0}^n\dbinom{n}{i}(-1)^i\sqrt 5^i\right) \\ &=\frac{1}{2^n\sqrt 5}\left(\sum\limits_{i=0}^{\left\lfloor\frac{n-1}2\right\rfloor}\dbinom{n}{2i+1}\cdot 2 \cdot \sqrt 5^{2i+1}\right) \\ &=\frac{1}{2^{n-1}\sqrt 5}\sum\limits_{i=0}^{\left\lfloor\frac{n-1}2\right\rfloor}\dbinom{n}{2i+1}\sqrt 5^{2i+1} \\ &=\frac{1}{2^{n-1}\sqrt 5}\left(\dbinom{n}{1}\sqrt 5+\dbinom{n}{3}\sqrt 5^3+\cdots+\dbinom{n}{2\left\lfloor\frac{n-1}2\right\rfloor+1}\sqrt 5^{\left(2\left\lfloor\frac{n-1}2\right\rfloor+1\right)}\right) \end{aligned}

那么有

\begin{gathered} F_{2p}=\frac{1}{2^{2p-1}\sqrt 5}\left(\dbinom{2p}1\sqrt 5+\dbinom{2p}3\sqrt 5^3+\cdots+\dbinom{2p}{2p-1}\sqrt 5^{2p-1}\right) \\ F_{2p+1}=\frac{1}{2^{2p}\sqrt 5}\left(\dbinom{2p}1\sqrt 5+\dbinom{2p}3\sqrt 5^3+\cdots+\dbinom{2p}{2p-1}\sqrt 5^{2p-1}\right) \end{gathered}

通过观察可以得到模 p 之后 F_{2p} 后面括号内只有 \dbinom{2p}p \equiv 2 \pmod p 保留了下来,其余的组合数均含 p 因子;F_{2p+1} 后面括号内只有 \dbinom{2p+1}1 \equiv 1 \pmod p\dbinom{2p+1}p \equiv 2 \pmod p\dbinom{2p+1}{2p+1} \equiv 1 \pmod p 三者保留了下来,其余组合数均含 p 因子。故通过费马小定理可得

\begin{aligned} F_{2p}&\equiv\frac{1}{2^{2p-1}\sqrt 5}\cdot \dbinom{2p}p\sqrt 5^p \\ &\equiv \left(\frac 12\right)^{2(p-1)}\cdot \frac12 \cdot2 \cdot (-1) \\ &\equiv-1 \pmod p \\ F_{2p+1}&\equiv\frac{1}{2^{2p}\sqrt 5}\left(\dbinom{2p+1}1\sqrt 5+\dbinom{2p+1}p\sqrt 5^p+\dbinom{2p+1}{2p+1}\sqrt 5^{2p+1}\right) \\ &\equiv \left(\frac 12\right)^{2(p-1)}\cdot\frac 14\cdot\left(1+2\cdot\sqrt 5^{p-1}+1\cdot\sqrt 5^{2p}\right) \\ &\equiv\frac{1-2+5^p}4 \\ &\equiv\frac{1-2+5}4 \\ &\equiv 1 \pmod p \end{aligned}

而又因为 F_1=F_2=1 得出 F_{-1}=1,F_{-2}=-1,也就是 F_{2p} \equiv F_{-2}F_{2p+1} \equiv F_{-1},所以周期为 2p+2

同理,通过二次互反律,可以得到 p \equiv 2,3 \pmod 5

但是!!!

我们忽略了两种情况。如果 p=2,那么 \dfrac12 没有意义;如果 p=5,那么 x^2\equiv 5 \pmod p 会有 x=0 这个解。所以,对于 p=2p=5 这两个情况,我们要特判。不难得到,\text{Pi}_2=3,\text{Pi}_5=20。(当然,如果有些人出于信仰用 1145140 也无大碍,只要是 320 的倍数即可,以此为证)

Part 2. 当 m=p^k \ (p \in \mathbb P, k \in \mathbb N)

结论 5:若 a \equiv 1 \pmod{p},那么 a^{p^k} \equiv 1 \pmod{p^{k+1}}

事实上,可以通过升幂定理的特殊形式证明:

  1. p 为奇素数,有 v_p(a^{p^k}-1)=v_p(a-1)+v_p(p^k)=v_p(a-1)+k。而 a-1 \equiv 0 \pmod p \Rightarrow v_p(a-1) \ge 1 得到 v_p(a^{p^k}-1)\ge k+1,即 a^{p^k}-1 \equiv 0 \pmod{p^{k+1}}
  2. p=2,有 v_2(a^{p^k}-1)=v_2(a-1)+v_2(a+1)+v_2(p^k)-1=v_2(a-1)+v_2(a+1)+k-1。由 a \equiv 1 \pmod 2 可得 a 为奇数,则 a+1 是偶数,也就是 v_2(a+1) \ge 1。所以 v_2(a^{p^k}-1) \ge 1+1+k-1=k+1,也就是 a^{p^k}-1 \equiv 0 \pmod{p^{k+1}}

关于升幂定理的内容以及证明见文末。

考虑数学归纳法。令 a^{p^k}=rp^{k+1}+1,由二项式展开得到:

\begin{aligned} a^{p^{k+1}}&=\left(a^{p^k}\right)^p \\ &=\sum\limits_{i=0}^p \dbinom{p}{i} r^ip^{(k+1)i} \end{aligned}

然而当 i \ge 2p^{(k+1)i} \equiv 0 \pmod{p^{k+2}},所以:

\begin{aligned} a^{p^{k+1}}&\equiv\dbinom{p}{0}+\dbinom{p}{1}rp^{k+1} \\ &\equiv 1+rp^{k+2} \\ &\equiv 1 \end{aligned} \pmod{p^{k+2}}

即证。

结论 6:对于素数 p,有

\text{Pi}_{p^{k-1}}|M \iff \text{Pi}_{p^k}|Mp

特别地,

M=\text{Pi}_{p^{k-1}} \iff Mp=\text{Pi}_{p^k}

证明:令 x_1=\dfrac{1+\sqrt 5}2, x_2=\dfrac{1-\sqrt 5}2,由于 F_M=\dfrac{1}{\sqrt 5}\left(x_1^M-x_2^M\right) \equiv 0 \pmod{p^{k-1}},且 F_{M+1}=\dfrac{1}{\sqrt 5}\left(x_1^{M+1}-x_2^{M+1}\right) \pmod{p^{k-1}}

所以有 x_1^M \equiv x_2^M \pmod{p^{k-1}}1 \equiv \dfrac{1}{\sqrt 5}\left(x_1^M \cdot x_1-x_2^M\cdot x_2\right) \equiv \dfrac{1}{\sqrt 5}x_1^M\left(x_1-x_2\right) \equiv x_1^M 。即 x_1^M \equiv x_2^M \equiv 1 \pmod{p^{k-1}}。以上步骤反方向也可推导,所以:

\text{Pi}_{p^{k-1}}|M \iff x_1^M \equiv x_2^M \equiv 1 \pmod{p^{k+1}}

而由 结论 5 可以得到 x_1^{Mp}\equiv x_2^{Mp} \equiv 1 \pmod{p^k},即:

\text{Pi}_{p^{k-1}}|M \iff x_1^M \equiv x_2^M \equiv 1 \pmod{p^{k+1}} \iff x_1^{Mp} \equiv x_2^{Mp} \equiv 1 \pmod{p^k} \equiv \text{Pi}_{p^k}|Mp

即证。因为周期等价,所以最小正周期也等价。

换句话说,要求模 p^k 意义下的斐波那契数列的周期长,只需用模 p 意义下的周期长乘以 p^{k-1} 即可。

Part 3. 当 m 为任意正整数

通过 结论 2 a \bot b \Rightarrow \text{Pi}_{ab}=\text{lcm}(\text{Pi}_a,\text{Pi}_b),我们只需将 m 变成 \prod\limits_{i=0}^kp_i^{c_i} 的形式,在一个一个求 \text{lcm} 即可。

总结

  1. 对模数 m 进行质因数分解。
  2. 对于 m 每个 p_i^{c_i},求出其周期长。
  3. 求周期长的最小公倍数。
  4. n 读入后模周期长得到 n',求出 F_{n'}

代码

#include<bits/stdc++.h>
using namespace std;
string s;
long long mod;
void read(string& s){
    char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)){
        s+=ch;
        ch=getchar();
    }
}
long long read(){
    long long s=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        s=s*10+(ch-'0');
        ch=getchar();
    }
    return s*f;
}
void write(const long long& x){
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
inline long long gcd(long long a, long long b){
    if(b==0) return a;
    else return gcd(b,a%b);
}
inline long long lcm(long long a, long long b){
    return a/gcd(a,b)*b;
}
inline long long qpow(long long a, long long b){
    long long ans=1;
    while(b){
        if(b&1) ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
pair<long long, long long> f(long long k){ // 递推式求斐波那契数列第 n 项,时间复杂度 O(log n),常数比矩乘小
    if(k==0) return {0,1};
    pair<long long,long long> p=f(k/2);
    long long tp1=p.first*((2*p.second%mod-p.first%mod+mod)%mod)%mod;
    long long tp2=(p.first*p.first%mod+p.second*p.second%mod)%mod;
    if(k&1) return {tp2,(tp1+tp2)%mod};
    else return {tp1,tp2};
}
inline long long getp(long long p){ // 求模 p 意义下周期长
    if(p==2) return 3;
    else if(p==5) return 20;
    else if(p%5==1||p%5==4) return p-1;
    else return 2*p+2;
}
inline long long getpk(long long p, long long k){ // 求模 p^k 意义下周期长
    return getp(p)*qpow(p,k-1);
}
inline long long get(long long x){ // 求模 x 意义下周期长
    long long ans=1;
    for(int i=2;i*i<=x;i++){ // 分解质因数
        if(x%i==0){
            int cnt=0;
            while(x%i==0) x/=i,cnt++;
            ans=lcm(ans,getpk(i,cnt));
        }
    }
    if(x!=1) ans=lcm(ans,getp(x));
    return ans;
}
int main(){
    read(s);
    mod=read();
    if(mod==1){
        puts("0");
        return 0;
    }
    long long circle=get(mod);
    long long n=0;
    for(int i=0;i<s.size();i++) n=(n*10+(s[i]-'0'))%circle;
    write(f(n).first);
    return 0;
}

关于 pair<long long, long long> f(long long) 函数:

这里没有用矩乘,而是用了这个递推式:

\left\{ \begin{aligned} &F_{2k}=F_k(2F_{k+1}-F_k) \\ &F_{2k+1}=F_k^2+F_{k+1}^2 \end{aligned} \right.

而这是极好证明的:

令矩阵 P=\begin{bmatrix} 0 & 1 \\ 1 & 1 \end{bmatrix},则有 P^n=\begin{bmatrix} F_{n-1} & F_n \\ F_n & F_{n+1} \end{bmatrix},即 \begin{bmatrix} F_{2n} & F_{2n+1} \end{bmatrix}=\begin{bmatrix} F_n & F_{n+1} \end{bmatrix} P^n 可以得出 \begin{bmatrix} F_{2n} & F_{2n+1} \end{bmatrix}=\begin{bmatrix} F_n & F_{n+1} \end{bmatrix}\begin{bmatrix} F_{n-1} & F_n \\ F_n & F_{n+1} \end{bmatrix},也就是说

\left\{ \begin{aligned} &F_{2n}=F_n\left(F_{n-1}+F_{n+1}\right)=F_n\left(F_{n+1}-F_n+F_{n+1}\right)=F_n\left(2F_{n+1}-F_n\right) \\ &F_{2n+1}=F_n^2+F_{n+1}^2 \end{aligned} \right.

即证。

关于升幂定理

v_p(n) 为素数 p 在整数 n 质因数分解后出现的个数,即 p^{v_p(n)} | np^{v_p(n)+1} \nmid n

  1. 前提:$n \in \mathbb N_+, p \nmid a, p \nmid b, a \equiv b \pmod p$。则有: $$ v_p(a^n-b^n)=v_p(a-b)+v_p(n) $$ 证明:设 $n=p^km$,其中 $\gcd(p,m)=1$,则 $k=v_p(n)$。 所以 $a^n-b^n=a^{p^km}-b^{p^km}=(a^{p^k}-b^{p^k})(a^{m-1}+a^{m-2}b+\cdots+b^{m-1})$。 而由 $a \equiv b \pmod p$ 得 $a^{m-1}+a^{m-2}b+\cdots+b^{m-1} \equiv m \cdot a^{m-1} \pmod p$,而其中 $p \nmid m, p \nmid a^{m-1}$,所以 $p \nmid ma^{m-1}$。 问题转而分析 $a^{p^k}-b^{p^k}$。若 $k=0$,则 $v_p(a^n-b^n)=v_p(p \cdot ma^{m-1})=1$,$v_p(a-b)+v_p(n)=1+0=1$,命题成立;若 $k>0$,记 $c=a^{p^{k-1}},d=b^{p^{k-1}}$。 则 $a^{p^k}-b^{p^k}=c^p-d^p=(c-d)(c^{p-1}+c^{p-2}d+\cdots+d^{p-1})$。而显然,由 $c \equiv d \pmod p$ 得到 $c^{p-1}+c^{p-2}d+\cdots+d^{p-2} \equiv p\cdot c^{p-1} \equiv 0 \pmod p$,也就是它能被 $p$ 整除。 令 $d=c+rp$。由二项式定理可得: $$ \begin{aligned} c^{p-1}+c^{p-2}d+\cdots+d^{p-1}&=\frac{d^p-c^p}{d-c} \\ &=\frac{(c+kp)^p-c^p}{kp} \\ &=\frac{\dbinom{p}{1}c^{p-1}kp+\dbinom{p}{2}c^{p-2}(kp)^2+\cdots+\dbinom{p}{p}c^0(kp)^p}{kp} \\ &=\dbinom{p}1c^{p-1}+\dbinom{p}2c^{p-2}kp+\cdots+\dbinom{p}p(kp)^{p-1} \\ &\equiv \dbinom{p}1c^{p-1} \pmod{p^2} \\ &\equiv pc^{p-1} \pmod{p^2} \\ &\equiv p(sp+1) \pmod{p^2} \text{ (Fermat's Little Theorem)}\\ &\equiv 1 \pmod{p^2} \end{aligned} $$ 即它不能被 $p^2$ 整除。也就是说,$v_p(c^{p-1}+c^{p-2}d+\cdots+d^{p-1})=1$。从而有 $$ \begin{aligned} v_p(a^{p^k}-b^{p^k})&=v_p(a^{p^{k-1}}-b^{p^{k-1}})+1 \\ &=v_p(a^{p^{k-2}}+b^{p^{k-2}})+2 \\ &=\cdots \\ &=v_p(a^{p^0}-b^{p^0})+k \\ &=v_p(a-b)+v_p(n) \end{aligned} $$ 即证。
  2. p=2

    前提:n \in \mathbb N_+,且 a,b 均为奇数。那么若 n 为奇数,则:

    v_2(a^n-b^n)=v_2(a-b)

    n 为偶数,则:

    v_2(a^n-b^n)=v_2(a-b)+v_2(a+b)+v_2(n)-1

    证明:设 n=2^km,其中 m 为奇数,则 k=v_2(n)。同理,有 a^n-b^n=a^{2^km}-b^{2^km}=(a^{2^k}-b^{2^k})(a^{m-1}+a^{m-2}b+\cdots+b^{m-1}),且 a^{m-1}+a^{m-2}b+\cdots+b^{m-1} 是奇数。当 k=0,即 n 为奇数,定理显然正确;当 k>0,同理记 c=a^{2^{k-1}},d=b^{2^{k-1}},有 a^{2^k}-b^{2^k}=c^2-d^2=(c-d)(c+d),由 c,d 为奇数可得 c+d 为偶数。然而当 k>1c=a^{2^{k-1}}=(a^{2^{k-2}})^2 为平方数,同理 d 也为平方数,则 c,d \equiv 1 \pmod 4,即 c+d \equiv 2 \pmod 4,因此 c+d 中只含一个 2。即

    \begin{aligned} v_2(a^n-b^n)&=v_2\left(a^{2^k}-b^{2^k}\right) \\ &=v_2(a^{2^{k-1}}-b^{2^{k-1}})+v_2(c+d) \\ &=v_2\left(a^{2^{k-1}}-b^{2^{k-1}}\right)+1 \\ &=v_2\left(a^{2^{k-2}}-b^{2^{k-2}}\right)+2 \\ &= \cdots \\ &=v_2\left(a^2-b^2\right)+(k-1) \end{aligned}

    k=1 时,a^2-b^2=(a-b)(a+b),在 \dfrac{a+b}2\dfrac{a-b}2 之间必然有一个不被 2 整除。这是因为 \dfrac{a+b}2-\dfrac{a-b}2=b 是奇数,从而有 v_p(a^2-b^2)=v_p(a-b)+v_p(a+b),也就是

    v_2(a^n-b^n)=v_2(a^2-b^2)+(k-1)=v_2(a-b)+v_2(a+b)+v_p(n)-1

    即证。