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整除,这就表明了斐波那契数列所含因子的周
期性,下面列举:
 因子:2,3,4,5, 6,7,8, 9,10,11,12
 周期:3,4,6,5,12,8,6,12,15,10,12
 我们称所生成的序列为剩余序列,那么一旦出现某个F(k) 能被N整除(这需证明我的一个猜想:对于任意
素数P,F(P),F(P-1)和F(P+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.
				
时间: 2024-10-14 22:34:57

FIB数列的相关文章

动态规划之Fib数列类问题应用

一,问题描述 有个小孩上楼梯,共有N阶楼梯,小孩一次可以上1阶,2阶或者3阶.走到N阶楼梯,一共有多少种走法? 二,问题分析 DP之自顶向下分析方式: 爬到第N阶楼梯,一共只有三种情况(全划分,加法原理),从第N-1阶爬1阶到第N阶:从第N-2阶爬2阶到第N阶:从第N-3爬3阶到第N阶. 故:way(N)=way(N-1)+way(N-2)+way(N-3) 这与求Fib数列非常相似,当然,其他类似的问题也可以这样求解. 初始条件: way(1)=1 way(2)=2 way(3)=4 三,代码

acm 之fib数列——java

1022. Fib数列 Description 定义Fib数列:1,1,2,3,5,8,13,… 求第N项除以2010的余数 Input Format 输入仅一行,为一个整数N Output Format 输出仅一行,为第N项除以2010的余数 Sample Input 3 Sample Output 2 Limits: 对于70%的数据 N≤1,000,000 对于100%的数据 N≤210,000,000,000 这道题最让人着急的是数太大了,而且不可以使用递归,这种方法会暴栈,但是java

HDU 1005 Number Sequence 矩阵乘法 Fib数列

原题: http://acm.hdu.edu.cn/showproblem.php?pid=1005 题目大意: 按规律求出第n项. 由矩阵乘法我们可以知道: 所以对于fib数列我们可以用矩阵来求,由于矩阵可以左乘右乘,所以我们可以用快速幂来优化. #include<iostream> #include"string.h" #include<stdio.h> using namespace std; const int bc=2; const int mod =

1022. Fib数列

Description 定义Fib数列:1,1,2,3,5,8,13,- 求第N 项除以2010 的余数 Input Format 输入仅一行,为一个整数N Output Format 输出仅一行,为第N 项除以2010 的余数 Sample Input 3 Sample Output 2 Limits: 对于70%的数据 N≤1,000,000 对于100%的数据 #include<iostream>using namespace std; int main(){    int t;    

UVaLive 3357 Pinary (Fib数列+递归)

题意:求第 k 个不含前导 0 和连续 1 的二进制串. 析:1,10,100,101,1000,...很容易发现长度为 i 的二进制串的个数正好就是Fib数列的第 i 个数,因为第 i 个也有子问题,其子问题也就是Fib,这样就可以用递归来解决了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include

[bzoj5118]Fib数列2_费马小定理_矩阵乘法

Fib数列2 bzoj-5118 题目大意:求Fib($2^n$). 注释:$1\le n\le 10^{15}$. 想法:开始一看觉得一定是道神题,多好的题面啊?结果...妈的,模数是质数,费马小定理就tm完事了,将fib数列的通项公式列出来然后费马小定理... 最后,附上丑陋的代码... ...(照着郭爷一顿瞎jb敲) #include <iostream> #include <cstdio> #include <cstring> #include <algo

Fib数列问题(项数很大)

用fib(n)表示斐波那契数列的第n项,现在要求你求fib(n) mod m.fib(1)= 1, fib(2)= 1. 输入格式 输入2个整数n(1≤n≤1018), m(2≤m≤10000000). 输出格式 输出fib(n)对m取模的值. 样例输入1 4 10 样例输出1 3 样例输入2 100000000 100000000 样例输出2 60546875 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long lo

fib数列变种题目

对一个正整数作如下操作:如果是偶数则除以2,如果是奇数则加1,如此进行直到1时操作停止,求经过9次操作变为1的数有多少个? 第9次操作:结果1由2产生.1个被操作数8:结果2只能由4产生.1个被操作数7:结果4由8.3产生.2个6:结果8由16.7产生:结果3由6产生.共3个5:结果16由32.15产生:结果7由14产生:结果6由12.5产生.共5个…每次操作,偶数(2除外)都由该数减1和该数的2倍得来,奇数只由该数的2倍得来各次操作的操作对象个数为:1,1,2,3,5,8,13,21,34,…

bzoj5118: Fib数列2(费马小定理+矩阵快速幂)

题目大意:求fib(2^n) 就是求fib矩阵的(2^n)次方%p,p是质数,根据费马小定理有 于是这题就完了 注意因为模数比较大会爆LL,得写快速乘法... #include<bits/stdc++.h> #define ll long long #define MOD(x) ((x)>=mod?(x-mod):(x)) using namespace std; const int maxn=500010; const ll mod=1125899839733759; struct m