数列公式

广义Fibonacci数列找循环节

我们两清 提交于 2019-11-29 11:26:54
遇到了2019ICPC南昌赛区的网络赛的一道题,fn=3*fn-1+2*fn-2,有多次询问求fn。总结起来其实就是在模P意义下,O(1)回答广义斐波那契额数列的第n项,可以说是一道模板题了。 这道题的解法有两种:①求出通项公式之后,用二次剩余+优化快速幂(可以k进制快速幂或者把快速幂分块)解决。②求出模P意义下的递推结果的循环节,然后给矩阵分块加速递推。 看到大佬说方法一因为受到二次剩余的局限(求出的根号可能在模P意义下开不了)并不是十分通用,这里就只提到了第二张办法。 首先是怎么 求广义斐波那契额数列模P意义下的循环节 呢? 这里给出 https://blog.csdn.net/code92007/article/details/98109917 这位大佬的办法 如果P是素数的话会简单一些 : ok,这道题求出循环节是(P-1)/2=499122176之后,因为有多组询问所以我们得想办法O(1)回答询问,关键在于怎么快速计算中间矩阵mat的n次幂mat^n,这里要用到一个矩阵分块的办法。 我们令块大小为kd=sqrt(循环节大小),那么我们让S数组计算mat^1->mat^kd,然后我们用P数组计算mat^kd,mat^2kd,mat^3kd....->mat^kd*kd,容易看到这个可以O(sqrt(n))计算得到,然后对于mat^n答案就是mat^(n%kd)*mat(n

剑指offer8-Fibonacci数列

可紊 提交于 2019-11-28 15:28:04
一 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39 二 解法1 1 分析 Fibonacci数列用数学语言描述可以表示为f(n) = f(n-1) + f(n-2), (n > 1); f(n) = n, (n = 0, 1);显然可以使用递归思想解决这个问题,递归公式与递归终止条件都有了。 复杂度:时间复杂度O(n^2),空间复杂度O(1)。 2 代码实现 1 class Solution { 2 public: 3 int Fibonacci(int n) { 4 if (n <= 0) 5 return 0; 6 if (n == 1) 7 return 1; 8 9 return Fibonacci(n - 1) + Fibonacci(n - 2); 10 } 11 }; 二 解法2 1 分析 用迭代代替递归,f(n) = f(n-1) + f(n-2),要计算f(n)就先计算f(n-1)、f(n-2),反过来想,只要知道f(1)、f(2),那么最终也可以知道f(n)。 复杂度:时间复杂度O(n),空间复杂度O(1)。 2 代码实现 1 class Solution { 2 public: 3 int Fibonacci(int n) { 4 if (n <= 0) 5 return 0; 6