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.

 


posted @ 2014-10-28 16:39  Kiss our dream  阅读(1557)  评论(0编辑  收藏  举报