FIB数列

斐波那契级数除以N会出现循环,此周期称为皮萨诺周期。

 下面给出证明

必然会出现循环
 这是基于下面事实:
 1. R(n+2)=F(n+2) mod P=(F(n+1)+F(n)) mod P=(F(n+1) mod p +F(n) modp) mod p
 2. 斐波那契数列的最大公约数定理:gcd(F(m),F(n))=F(gcd(m,n))
 最大公约数定理表明如果F(k)能被N整除,则F(ik)也能被N整除,这就表明了斐波那契数列所含因子的周
期性,下面列举:
 因子:2345, 678, 9101112
 周期:3465128612151012
 我们称所生成的序列为剩余序列,那么一旦出现某个F(k) 能被N整除(这需证明我的一个猜想:对于任意
素数PFP),FP-1)和FP+1)三个中定有一个能被P整除),以后F(ik)都能被N整除,亦即剩余
序列周期地出现0
下一个剩余序列值为N-1种可能,总会重复,有两个相邻的重复该序列就一定重复,亦即具有周期性。
 这个周期叫做皮萨诺周期


而这个周期长度不会超过6P

当我们所要求的Fib数列项数特别大的时候,我们就可以用周期性来优化了

下面给个快速幂矩阵的FIB数列代码

const mol=10000007;



type matrix=array[1..2,1..2] of int64;

var

    c,cc:matrix;

    n:int64;



function multiply(x,y:matrix):matrix; inline;

var temp:matrix;

begin

    temp[1,1]:=(x[1,1]*y[1,1]+x[1,2]*y[2,1]) mod mol;

    temp[1,2]:=(x[1,1]*y[1,2]+x[1,2]*y[2,2]) mod mol;

    temp[2,1]:=(x[2,1]*y[1,1]+x[2,2]*y[2,1]) mod mol;

    temp[2,2]:=(x[2,1]*y[1,2]+x[2,2]*y[2,2]) mod mol;

    exit(temp);

end;



function getcc(n:int64):matrix; inline;

var temp:matrix;

    t:int64;

begin

    if n=1 then exit(c);

    t:=n>>1;

    temp:=getcc(t);

    temp:=multiply(temp,temp);

    if (n and 1)=1 then exit(multiply(temp,c))

    else exit(temp);

end;



procedure init;

begin

    readln(n);

    c[1,1]:=1;

    c[1,2]:=1;

    c[2,1]:=1;

    c[2,2]:=0;

    if n=1 then

        begin

            writeln(1);

            halt;

        end;

    if n=2 then

        begin

            writeln(1);

            halt;

        end;

    cc:=getcc(n-2);

end;



procedure work;

begin

    writeln(int64(cc[1,1]+cc[1,2]) mod mol);

end;



begin

    init;

    work;

end.

 



                            

你可能感兴趣的:(列)