Description

看题戳我 给你一个序列,要求支持区间加斐波那契数列和区间求和。\(~n \leq 3 \times 10 ^ 5, ~fib_1 = fib_2 = 1~\).

Solution

​ 先来考虑一段斐波那契数列如何快速求和,根据性质有

\[\begin {align}
fib_n &= fib_{n - 1} + fib_{n - 2} \\
&= fib_ {n - 2} + fib_{n - 3} + fib_{n - 2} \\
&= fib_{n - 3} + fib_{n - 4} + fib_{n - 3} + fib_{n - 2} \\
&= \dots \\
&= fib_2 + \sum_{i = 1}^{n - 2} {fib_i}
\end {align}
\]

​ 可以发现这里有个\(~\sum_{i = 1} ^ {n - 2} {fib_i}\),转换一下就是\(~\sum_{i = 1} ^ {n}fib_i = fib_{n + 2} - fib_2\).而两个斐波那契数列对应项加起来之后还是一个类斐波那契数列,记为\(~S_i\),设这个类斐波那契数列的起始项\(S_1 = a, S_2 = b\),显然有\(~S_i = a \times fib_{i - 2} + b \times fib_{i - 1}\).那么对于一段类斐波那契数列的求和,我们只要记起始的两项和这段数列的长度即可。现在可以用简单的线段树区间加来维护了,\(~PushDown~\)操作有一点细节,注意要分开算区间的前两项。具体看代码。。

Code

  1. #include<bits/stdc++.h>
  2. #define For(i, j, k) for(int i = j; i <= k; ++i)
  3. #define Forr(i, j, k) for(int i = j; i >= k; --i)
  4. using namespace std;
  5. inline int read() {
  6. int x = 0, p = 1; char c = getchar();
  7. for(; !isdigit(c); c = getchar()) if(c == '-') p = -1;
  8. for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  9. return x *= p;
  10. }
  11. inline void File() {
  12. freopen("cf446c.in", "r", stdin);
  13. freopen("cf446c.out", "w", stdout);
  14. }
  15. const int N = 3e5 + 10, mod = 1e9 + 9;
  16. int n, m, fib[N];
  17. inline int add(int a, int b) { return (a += b) >= mod ? a - mod : a; }
  18. namespace SGT {
  19. #define lc (rt << 1)
  20. #define rc (rt << 1 | 1)
  21. #define mid (l + r >> 1)
  22. #define lson lc, l, mid
  23. #define rson rc, mid + 1, r
  24. int tr[N << 2], t1[N << 2], t2[N << 2];
  25. inline void pushup(int rt) { tr[rt] = (tr[lc] + tr[rc]) % mod; }
  26. inline int S(int a, int b, int x) {
  27. return x == 1 ? a : (x == 2 ? b : (1ll * a * fib[x - 2] + 1ll * b * fib[x - 1]) % mod);
  28. }
  29. inline int sum(int a, int b, int x) {
  30. return x == 1 ? a : (x == 2 ? add(a, b) : (S(a, b, x + 2) - b + mod) % mod);
  31. }
  32. inline void pushdown(int rt, int l, int r) {
  33. if (t1[rt]) {
  34. t1[lc] = add(t1[lc], t1[rt]), t2[lc] = add(t2[lc], t2[rt]);
  35. tr[lc] = add(tr[lc], sum(t1[rt], t2[rt], mid - l + 1));
  36. int T1 = S(t1[rt], t2[rt], mid - l + 2), T2 = S(t1[rt], t2[rt], mid - l + 3);
  37. t1[rc] = add(t1[rc], T1), t2[rc] = add(t2[rc], T2);
  38. tr[rc] = add(tr[rc], sum(T1, T2, r - mid));
  39. t1[rt] = t2[rt] = 0;
  40. }
  41. }
  42. inline void build(int rt, int l, int r) {
  43. if (l == r) tr[rt] = read();
  44. else build(lson), build(rson), pushup(rt);
  45. }
  46. inline void update(int rt, int l, int r, int L, int R) {
  47. if (L <= l && r <= R) {
  48. tr[rt] = add(tr[rt], sum(fib[l - L + 1], fib[l - L + 2], r - l + 1));
  49. t1[rt] = add(t1[rt], fib[l - L + 1]); t2[rt] = add(t2[rt], fib[l - L + 2]);
  50. return ;
  51. }
  52. pushdown(rt, l, r);
  53. if (L <= mid) update(lson, L, R);
  54. if (R > mid) update(rson, L, R);
  55. pushup(rt);
  56. }
  57. inline int query(int rt, int l, int r, int L, int R) {
  58. if (L <= l && r <= R) return tr[rt];
  59. pushdown(rt, l, r); int res = 0;
  60. if (L <= mid) res = add(res, query(lson, L, R));
  61. if (R > mid) res = add(res, query(rson, L, R));
  62. return pushup(rt), res;
  63. }
  64. #undef lc
  65. #undef rc
  66. #undef mid
  67. #undef lson
  68. #undef rson
  69. }
  70. int main() {
  71. File();
  72. n = read(), m = read();
  73. fib[1] = fib[2] = 1;
  74. For(i, 3, n + 5) fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
  75. using namespace SGT;
  76. build(1, 1, n);
  77. while (m --) {
  78. int opt = read(), l = read(), r = read();
  79. opt == 1 ? update(1, 1, n, l, r), 1 : printf("%d\n", query(1, 1, n, l, r)), 1;
  80. }
  81. return 0;
  82. }

【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)的更多相关文章

  1. CF446C DZY Loves Fibonacci Numbers 线段树 + 数学

    有两个性质需要知道: $1.$ 对于任意的 $f[i]=f[i-1]+f[i-2]$ 的数列,都有 $f[i]=fib[i-2]\times f[1]+fib[i-1]\times f[2]$ 其中 ...

  2. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  3. Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  4. ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)

    Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...

  5. codeforces 446C DZY Loves Fibonacci Numbers 线段树

    假如F[1] = a, F[2] = B, F[n] = F[n - 1] + F[n - 2]. 写成矩阵表示形式可以很快发现F[n] = f[n - 1] * b + f[n - 2] * a. ...

  6. Codeforces446C DZY Loves Fibonacci Numbers(线段树 or 分块?)

    第一次看到段更斐波那契数列的,整个人都不会好了.事后看了题解才明白了一些. 首先利用二次剩余的知识,以及一些数列递推式子有下面的 至于怎么解出x^2==5(mod 10^9+9),我就不知道了,但是要 ...

  7. Codeforces 446C DZY Loves Fibonacci Numbers [线段树,数论]

    洛谷 Codeforces 思路 这题知道结论就是水题,不知道就是神仙题-- 斐波那契数有这样一个性质:\(f_{n+m}=f_{n+1}f_m+f_{n}f_{m-1}\). 至于怎么证明嘛-- 即 ...

  8. 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers

    我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...

  9. cf446C DZY Loves Fibonacci Numbers

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

随机推荐

  1. MySQL左连接时 返回的记录条数 比 左边表 数量多

    在学MySQL的连接时,为了便于记忆,就将左连接 记做 最后结果的总记录数 和 进行左连接的左表的记录数相同,简单的说就是下面这个公式 count(table A left join table B) ...

  2. 【学习总结】Git学习-参考廖雪峰老师教程九-使用码云

    学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...

  3. 解决scrapy报错:ModuleNotFoundError: No module named 'win32api'

    ModuleNotFoundError: No module named 'win32api' 表示win32api未安装 解决办法: 下载对应python版本的win32api,并安装. 下载地址: ...

  4. [转帖]linux sed命令

    linux sed命令就是这么简单 https://www.cnblogs.com/wangqiguo/p/6718512.html 用到的最多的就是一个sed -i 's/nn/mm/' 的命令了. ...

  5. spring bean之间的关系:继承,依赖,注入

    一 继承 spring中多个bean之间的继承关系,和面向对象中的继承关系类似,直接看代码. 先定义一个Person类 package com.demo.spring.entity; /** * @a ...

  6. JDK 环境变量的设置、eclipse、Tomcat的配置

    一.JDK的环境变量的设置 环境变量设置: JDK下载好后,(1)选择电脑属性-高级系统设置-高级-环境变量,接着在系统变量中(2)新建JAVA_HOME,变量值设置为下载好后JDK在电脑中的路径;( ...

  7. spring boot session error

    Error starting ApplicationContext. To display the conditions report re-run your application with 'de ...

  8. Spring Boot基础:Spring Boot简介与快速搭建(1)

    1. Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的创建.运行.调试.部署等. Spring Boot默认使用tomca ...

  9. delphi中 dataset容易出错的地方

    最近写delphi项目,用到的数据集中的dataset,一直修改exception啊,写下过程. 在对数据集进行任何操作之前,首先要打开数据集.要打开数据集,可以把Active属性设为True,例如: ...

  10. js4

    数组的解构赋值: 位置对象的解构赋值: 名称 // {}在解构赋值的时候,不能出现在一行的最前面,否则js解析器会把他当成一个代码块,加()({a, b} = obj),告诉他这个仅仅是一个解构语句 ...