\(\text{Problem}\)

\(\text{Solution}\)

\(\text{Fibonacci}\) 数列有一个性质:若 \(H_1=a,H_2=b,H_n=H_{n-2}+H_{n-1}\)

则有 \(H_n=a\cdot F_{n-2}+b\cdot F_{n-1}\)

有了这个性质后,对一段区间加斐波那契数列后,我们可以 \(O(1)\) 知道任意一位加的数是多少(当然是预处理出斐波那契数列后)

也就是说维护这段区间前两位加的数 \({a,b}\) 即可

对于一段区间求区间和即 \(ans=a\cdot[(\sum_{i=1}^{r-l-1}F_i)+1]+b\cdot\sum_{i=1}^{r-l}F_i\)

线段树维护每段区间加的 \(a,b\) 即可

\(\text{Code}\)

#include<cstdio>
#define ls (p << 1)
#define rs (ls | 1)
typedef long long LL;
using namespace std; const int N = 1e5 + 5;
const LL P = 1e9 + 9;
int n, m;
LL a[N], F[N], sF[N];
LL sum[N * 4], tg1[N * 4], tg2[N * 4]; void pushup(int p) {sum[p] = (sum[ls] + sum[rs]) % P;}
void update1(int l, int r, int p, int x, int v)
{
if (l == r) return void(tg1[p] = sum[p] = v);
int mid = (l + r) >> 1;
if (x <= mid) update1(l, mid, ls, x, v);
else update1(mid + 1, r, rs, x, v);
pushup(p);
}
void change(int l, int r, int p, LL v1, LL v2)
{
sum[p] = (sum[p] + v1 * (sF[(r - l - 1)<0?0:(r - l - 1)] + 1) % P + v2 * sF[r - l] % P) % P;
tg1[p] = (tg1[p] + v1) % P, tg2[p] = (tg2[p] + v2) % P;
}
void pushdown(int l, int r, int p)
{
if (!tg1[p] && !tg2[p]) return;
int mid = (l + r) >> 1;
change(l, mid, ls, tg1[p], tg2[p]);
LL v1 = (tg1[p] * F[mid - l] % P + tg2[p] * F[mid - l + 1] % P) % P;
LL v2 = (tg1[p] * F[mid - l + 1] % P + tg2[p] * F[mid - l + 2] % P) % P;
change(mid + 1, r, rs, v1, v2);
tg1[p] = 0, tg2[p] = 0;
}
void update2(int l, int r, int p, int x, int y, LL v1, LL v2)
{
if (x <= l && r <= y) return void(change(l, r, p, v1, v2));
int mid = (l + r) >> 1;
pushdown(l, r, p);
if (x <= mid) update2(l, mid, ls, x, y, v1, v2);
LL a = v1, b = v2;
if (l <= x && x <= mid) a = (v1 * F[mid - x] % P + v2 * F[mid - x + 1] % P) % P,
b = (v1 * F[mid - x + 1] % P + v2 * F[mid - x + 2] % P) % P;
else if (l > x && x <= mid) a = (v1 * F[mid - l] % P + v2 * F[mid - l + 1] % P) % P,
b = (v1 * F[mid - l + 1] % P + v2 * F[mid - l + 2] % P) % P;
if (y > mid) update2(mid + 1, r, rs, x, y, a, b);
pushup(p);
}
LL query(int l, int r, int p, int x, int y)
{
if (x <= l && r <= y) return sum[p];
int mid = (l + r) >> 1; LL ret = 0;
pushdown(l, r, p);
if (x <= mid) ret = query(l, mid, ls, x, y);
if (y > mid) ret = (ret + query(mid + 1, r, rs, x, y)) % P;
return ret;
} int main()
{
scanf("%d%d", &n, &m);
for(int i = 1, x; i <= n; i++) scanf("%d", &x), update1(1, n, 1, i, x);
F[1] = 1, F[2] = 1, sF[1] = 1, sF[2] = 2;
for(int i = 3; i <= n; i++) F[i] = (F[i - 1] + F[i - 2]) % P;
for(int i = 3; i <= n; i++) sF[i] = (sF[i - 1] + F[i]) % P;
for(int op, l, r; m; --m)
{
scanf("%d%d%d", &op, &l, &r);
if (op == 1) update2(1, n, 1, l, r, F[1], F[2]);
else printf("%lld\n", query(1, n, 1, l, r));
}
}

JZOJ.4724 斐波那契的更多相关文章

  1. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. python迭代器实现斐波拉契求值

    斐波那契数列(Fibonacci sequence),又称黄金分割数列,也称为"兔子数列":F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*).例 ...

  3. Ural 1225. Flags 斐波那契DP

    1225. Flags Time limit: 1.0 secondMemory limit: 64 MB On the Day of the Flag of Russia a shop-owner ...

  4. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

  5. js中的斐波那契数列法

    //斐波那契数列:1,2,3,5,8,13…… //从第3个起的第n个等于前两个之和 //解法1: var n1 = 1,n2 = 2; for(var i=3;i<101;i++){ var ...

  6. 剑指Offer面试题:8.斐波那契数列

    一.题目:斐波那契数列 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 二.效率很低的解法 很多C/C++/C#/Java语言教科书在讲述递归函数的时 ...

  7. 算法: 斐波那契数列C/C++实现

    斐波那契数列: 1,1,2,3,5,8,13,21,34,....     //求斐波那契数列第n项的值 //1,1,2,3,5,8,13,21,34... //1.递归: //缺点:当n过大时,递归 ...

  8. 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

    P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...

  9. Python递归及斐波那契数列

    递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可 ...

  10. 简单Java算法程序实现!斐波那契数列函数~

    java编程基础--斐波那契数列 问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 思路:可能出现的情况:(1) n=1 ,一种方法 ;(2)n=2 ...

随机推荐

  1. 在Windows模拟器中使用LVGL8.3

    引言 LVGL是一个跨平台.轻量级.易于移植的图形库.也因其支持大量特性和其易于裁剪,配置开关众多,且版本升级较快,不同版本之间存在一定的差异性,相关的使用教程有一定的滞后性,由于缺少最新版本的中文教 ...

  2. Spring01:概述、工厂模式解耦、Spring中的IOC

    四天课程安排 第一天:Spring框架的概述.Spring中基于XML的IOC配置 第二天: Spring中基于注解的IOC和IOC的案例(单表增删改查,持久层随意) 第三天:Spring中的AOP和 ...

  3. 【每日一题】【快速排序过程、循环过程无=、递归参数】2022年1月16日-NC140 排序

    快速排序 对时间复杂度和空间复杂度有要求 方法1:快速排序-递归 import java.util.*; public class Solution { /** * 代码中的类名.方法名.参数名已经指 ...

  4. TypeScript 之 Interface

    Interface 描述:用来描述对象的形状,能够被继承 常用语法 ( Common Syntax ) 1. 描述普通对象 interface JsonResponse { version:numbe ...

  5. elasticsearch倒排索引(全面了解)

    SimpleAI推荐语: 前年转过这篇文章,最近在看检索相关论文,发现又有点忘记倒排索引(inverted index)的具体内容,遂翻出来再看看,不得不说,这个漫画画的太好了,娓娓道来,一看就懂,再 ...

  6. 如何查看计算机的CPU信息

    CPU-Z是一款家喻户晓的CPU检测软件,是检测CPU使用程度极高的一款软件.它支持的CPU种类相当全面,软件的启动速度及检测速度都很快.另外,它还能检测主板和内存的相关信息,其中就有我们常用的内存双 ...

  7. 使用pip命令安装库时提示Could not build wheels for six, since package 'wheel' is not installed

    在使用pip命令安装库时提示Could not build wheels for six, since package 'wheel' is not installed 解决以上问题可用 pip in ...

  8. 【机器学习】李宏毅——Anomaly Detection(异常检测)

    异常检测概述 首先要明确一下什么是异常检测任务.对于异常检测任务来说,我们希望能够通过现有的样本来训练一个架构,它能够根据输入与现有样本之间是否足够相似,来告诉我们这个输入是否是异常的,例如下图: 那 ...

  9. overflow_auto在flex_1的容器失效

    旧文章从语雀迁移过来,原日期为2022-02-22 我们经常使用flex:1来动态分配父容器剩余空间,这时候如果要在容器上增加滚动条,使用overflow: auto可能会失效. 原因: 一般原因:因 ...

  10. 2022年7月13日,第四组,周鹏,JS做计算器代码

    代码不难,看了我前面笔记的应该能看懂. 没看?(= ̄ω ̄=)喵了个咪(๑‾᷅^‾᷅๑) 嫌弃你 还看啥,去看啊!要不直接复制代码吧!( ̄へ ̄)( ̄へ ̄)( ̄へ ̄) Document 0 / * - 7 ...