Fibonacci数列定义为

$$f_n = f_{n-1}+f_{n-2}, \text{以及初值}f_0=0, f_1=1.$$

本文之讨论,皆在模$10^9+7$意义下。

FIBOSUM

给定$0 \le x \le y \le 10^9$,求$\sum_{i=x}^y f_i$。

解:

令$s_n = \sum_{i=1}^n f_i$,则

$$\begin{bmatrix} 1 & 1 & 0 \\ 0 & 1 & 1 \\ 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} s_{n-1} \\ f_n \\ f_{n-1} \end{bmatrix} = \begin{bmatrix} s_n \\ f_{n+1} \\ f_n \end{bmatrix}$$

于是$\sum_{i=x}^y f_i = s_y - s_{x-1}$,可用矩阵快速幂$O(\log x + \log y)$解决。

FIBOSUM2

给定$0 \le c < k \le 2^{15}$,以及$0 < n \le 10^{18}$,求

$$\sum_{i=1}^n f_{ki+c}.$$

解:

$$M = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}$$

$$M \begin{bmatrix} f_n \\ f_{n-1} \end{bmatrix} = \begin{bmatrix} f_{n+1} \\ f_n \end{bmatrix}$$

$$M^n = \begin{bmatrix} f_{n+1} & f_n \\ f_n & f_{n-1} \end{bmatrix}$$

于是$(M^n)_{01} = f_n$,

$$\left( \sum_{i=x}^y M^i \right)_{01} = \sum_{i=x}^y f_i$$

进而

$$ \left( \sum_{i=1}^n M^{ki+c} \right)_{01} = \sum_{i=1}^n f_{ki+c}$$

借此我们令

$$A = \begin{bmatrix} I & M^k \\ 0 & M^k \end{bmatrix}$$

可以验证

$$A^n \begin{bmatrix} 0 \\ M^c \end{bmatrix} = \begin{bmatrix} \sum_{i=1}^n M^{ki+c} \\ M^{kn+c} \end{bmatrix}$$

可以利用矩阵快速幂在$O(4^3 \log n)$求得。

这样复杂度太高,我们继续优化。

设$f(\lambda) = \det (\lambda I - A)$是矩阵$A$的特征多项式,即

$$f(\lambda) = \lambda^4 - a_1 \lambda^3 - a_2 \lambda^2 - a_3 \lambda - a_4. $$

其中$a_1 = f_{k+1}+f_{k-1}+2, a_2 = -(f_{k+1}f_{k-1}-f_k^2+2(f_{k+1}+f_{k-1})+1), a_3 = 2(f_{k+1}f_{k-1}-f_kf_k)+f_{k+1}+f_{k-1}, a_4 = f_k^2-f_{k+1}f_{k-1}.$

由Hamilton-Cayley定理,$f(A) = 0$,即

$$A^4 = a_1 A^3 + a_2 A^2 + a_3 A + a_4 I.$$

于是我们可以利用多项式乘法,把$A^n$化为$A$的三次多项式。

假设$A^n = c_3 A^3 + c_2 A^2 + c_1 A^1 + c_4$,并令$s_n = \sum_{i=1}^n f_{ki+c}$,有

$$s_n = \sum_{i=0}^3 c_is_i = c_1s_1+c_2s_2+c_3s_3$$

时间复杂度$O(4^2 \log n)$。

我们仍可继续优化,考虑到Fibonacci数列在模$10^9+7$下的循环节是$2 \times 10^9+16$,并且

$$\sum_{i=1}^{2 \times 10^9+16} f_{ki+c} \equiv \sum_{i=1}^{2 \times 10^9+16} f_{i} \equiv 0 \pmod {10^9+7}.$$

于是

$$s_n \equiv s_{n \bmod (2 \times 10^9+16)}.$$

则可以把$n$限制到 int 范围内。

P.S. 可构造3阶矩阵。令

$$ A = \begin{bmatrix} 1 & 1 & 0 \\ 0 & f_{k+1} & f_k \\ 0 & f_k & f_{k-1}  \end{bmatrix}. $$

$$ A^n \begin{bmatrix} 0 \\ f_{k+c} \\ f_{k+c-1} \end{bmatrix} = \begin{bmatrix} s_n \\ f_{k(n+1)+c} \\ f_{k(n+1)+c-1} \end{bmatrix}. $$

其特征函数$f(\lambda) = \lambda^3 - a_1 \lambda^2 - a_2 \lambda - a_3$,其中 $a_1 = f_{k+1}+f_{k-1}+1, a_2 = f_k^2-f_{k+1}f_{k-1}-f_{k+1}-f_{k-1}, a_3 = f_{k+1}f_{k-1}-f_k^2$。时间复杂度$O(3^2 \log n)$。

SPOJ FIBOSUM && FIBOSUM2的更多相关文章

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  2. SPOJ DQUERY D-query(主席树)

    题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...

  3. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  4. 【填坑向】spoj COT/bzoj2588 Count on a tree

    这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...

  5. SPOJ bsubstr

    题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...

  6. 【SPOJ 7258】Lexicographical Substring Search

    http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...

  7. 【SPOJ 1812】Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...

  8. 【SPOJ 8222】Substrings

    http://www.spoj.com/problems/NSUBSTR/ clj课件里的例题 用结构体+指针写完模板后发现要访问所有的节点,改成数组会更方便些..于是改成了数组... 这道题重点是求 ...

  9. SPOJ GSS2 Can you answer these queries II

    Time Limit: 1000MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description Being a ...

随机推荐

  1. 一步步走向国际乱码大赛-- 恶搞C语言

    大家都一直强调规范编码.可是这个世界上有个大师们娱乐的竞赛--国际乱码大赛. 能写出来的都是对语言深入了解的master.我从没想自己也能"恶搞"C,一直都是老老实实编码.就在前几 ...

  2. uwsgi 热启动

    uwsgi文件每次启动都要kill进程,这样非常麻烦,理想的情况是须要改动文件就自己主动生效,经查阅资料.发现uwsgi是自带该功能的,该功能的配置节例如以下 <uwsgi> <py ...

  3. BUPT复试专题—最长连续等差子数列(2014软院)

    题目描述   给定-个长度为N的整数数列,你需要在其中找到最长的连续子数列的长度, 并满足这个子数列是等差的.注意公差小于或等于0的情况也是允许的. 输入 第一行为数据组数T(1~100),表示测试数 ...

  4. CentOS下常用的 19 条命令

    玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命令就可以了.当然你也可以在使用时去找一下 ...

  5. 封装算法: 模板方法(Template Method)模式

    template method(模板方法)模式是一种行为型设计模式.它在一个方法中定义了算法的骨架(这种方法被称为template method.模板方法),并将算法的详细步骤放到子类中去实现.tem ...

  6. 2015 Multi-University Training Contest 3--1011 Work

    代码: #include<cstdio> #include<cstring> using namespace std; int n,k; int father[105],son ...

  7. 从头学起-CLR的执行模型

    1.将源代码编译成托管代码 公共运行时(Common Language Runtime) a.面向运行时的所有语言都可以通过异常报告错误 b.面向运行时的所有语言都可以创建线程 c.核心功能:管理内存 ...

  8. DASH----Desktop and mobile Architecture for System Hardware----桌面和移动系统硬件架构(DASH)计划

    http://baike.baidu.com/subview/813787/11301142.htm http://sites.amd.com/cn/business/it-solutions/man ...

  9. 使用Java绘制验证码

    效果图: JDemo.java import java.io.File; import java.io.IOException; import static java.lang.System.out; ...

  10. vue实现单选多选反选全选全不选

    单选 当我们用v-for渲染一组数据的时候,我们可以带上index以便区分他们我们这里利用这个index来简单地实现单选 <li v-for="(item,index) in radi ...