【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)
Description
看题戳我 给你一个序列,要求支持区间加斐波那契数列和区间求和。\(~n \leq 3 \times 10 ^ 5, ~fib_1 = fib_2 = 1~\).
Solution
先来考虑一段斐波那契数列如何快速求和,根据性质有
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
#include<bits/stdc++.h>
#define For(i, j, k) for(int i = j; i <= k; ++i)
#define Forr(i, j, k) for(int i = j; i >= k; --i)
using namespace std;
inline int read() {
int x = 0, p = 1; char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') p = -1;
for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x *= p;
}
inline void File() {
freopen("cf446c.in", "r", stdin);
freopen("cf446c.out", "w", stdout);
}
const int N = 3e5 + 10, mod = 1e9 + 9;
int n, m, fib[N];
inline int add(int a, int b) { return (a += b) >= mod ? a - mod : a; }
namespace SGT {
#define lc (rt << 1)
#define rc (rt << 1 | 1)
#define mid (l + r >> 1)
#define lson lc, l, mid
#define rson rc, mid + 1, r
int tr[N << 2], t1[N << 2], t2[N << 2];
inline void pushup(int rt) { tr[rt] = (tr[lc] + tr[rc]) % mod; }
inline int S(int a, int b, int x) {
return x == 1 ? a : (x == 2 ? b : (1ll * a * fib[x - 2] + 1ll * b * fib[x - 1]) % mod);
}
inline int sum(int a, int b, int x) {
return x == 1 ? a : (x == 2 ? add(a, b) : (S(a, b, x + 2) - b + mod) % mod);
}
inline void pushdown(int rt, int l, int r) {
if (t1[rt]) {
t1[lc] = add(t1[lc], t1[rt]), t2[lc] = add(t2[lc], t2[rt]);
tr[lc] = add(tr[lc], sum(t1[rt], t2[rt], mid - l + 1));
int T1 = S(t1[rt], t2[rt], mid - l + 2), T2 = S(t1[rt], t2[rt], mid - l + 3);
t1[rc] = add(t1[rc], T1), t2[rc] = add(t2[rc], T2);
tr[rc] = add(tr[rc], sum(T1, T2, r - mid));
t1[rt] = t2[rt] = 0;
}
}
inline void build(int rt, int l, int r) {
if (l == r) tr[rt] = read();
else build(lson), build(rson), pushup(rt);
}
inline void update(int rt, int l, int r, int L, int R) {
if (L <= l && r <= R) {
tr[rt] = add(tr[rt], sum(fib[l - L + 1], fib[l - L + 2], r - l + 1));
t1[rt] = add(t1[rt], fib[l - L + 1]); t2[rt] = add(t2[rt], fib[l - L + 2]);
return ;
}
pushdown(rt, l, r);
if (L <= mid) update(lson, L, R);
if (R > mid) update(rson, L, R);
pushup(rt);
}
inline int query(int rt, int l, int r, int L, int R) {
if (L <= l && r <= R) return tr[rt];
pushdown(rt, l, r); int res = 0;
if (L <= mid) res = add(res, query(lson, L, R));
if (R > mid) res = add(res, query(rson, L, R));
return pushup(rt), res;
}
#undef lc
#undef rc
#undef mid
#undef lson
#undef rson
}
int main() {
File();
n = read(), m = read();
fib[1] = fib[2] = 1;
For(i, 3, n + 5) fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
using namespace SGT;
build(1, 1, n);
while (m --) {
int opt = read(), l = read(), r = read();
opt == 1 ? update(1, 1, n, l, r), 1 : printf("%d\n", query(1, 1, n, l, r)), 1;
}
return 0;
}
【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)的更多相关文章
- 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]$ 其中 ...
- [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)
[Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...
- 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 ...
- ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)
Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...
- 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. ...
- Codeforces446C DZY Loves Fibonacci Numbers(线段树 or 分块?)
第一次看到段更斐波那契数列的,整个人都不会好了.事后看了题解才明白了一些. 首先利用二次剩余的知识,以及一些数列递推式子有下面的 至于怎么解出x^2==5(mod 10^9+9),我就不知道了,但是要 ...
- Codeforces 446C DZY Loves Fibonacci Numbers [线段树,数论]
洛谷 Codeforces 思路 这题知道结论就是水题,不知道就是神仙题-- 斐波那契数有这样一个性质:\(f_{n+m}=f_{n+1}f_m+f_{n}f_{m-1}\). 至于怎么证明嘛-- 即 ...
- 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers
我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...
- cf446C DZY Loves Fibonacci Numbers
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
随机推荐
- Mysql数据库触发器调用脚本
一.数据库触发器 mysql触发器trigger 实例详解 对数据库触发器new和old的理解 示例 二.UDF mySql的UDF是什么 三.安装执行命令UDF mysql触发器调用外部脚本(安装) ...
- JQuery 的Ajax的使用
JSON:一种轻量级的数据表示方法,优点:传输方便,占用字节少 XML:一种偏重量级的数据表示方法,优点:格式清晰,占用字节多,大量的字节都浪费在了标签上: 网络传输我们常使用json,因为浏览器解析 ...
- SDK安装详解以及adb的来源
首先,下载Android SDK Tools,翻过墙的朋友可以去Google Android的官网上下载(http://developer.android.com/sdk/index.html) 选择 ...
- 第四章 MyBatis-SQL映射文件
MyBatis 真正的强大在于映射语句,专注于SQL,功能强大,SQL映射的配置却是相当简单 SQL映射文件的几个顶级元素(按照定义的顺序) mapper - namespace cache - 配置 ...
- Vector源码分析
Vector与ArrayList底层实现基本类似,底层都是用数组实现的,最大的不同是Vector是线程安全的.ArrayList源码分析请参考ArrayList源码分析 一.源码分析 基于jdk1.7 ...
- C# 往Datatable中添加新行的步骤
以一个实例说明 //录入年份绑定 public void YearList(FineUIPro.DropDownList ddlYear) { //年份从15年到当前年//起止年份 ; int yea ...
- C#设计模式之5:简单工厂和工厂方法模式
工厂模式包含三种,简单工厂模式,工厂方法模式,抽象工厂模式.这三种都是解决了一个问题,那就是对象的创建问题.他们的职责就是将对象的创建和对象的使用分离开来. 当我们创建对象的时候,总是会new一个对象 ...
- [转帖]web安全:通俗易懂,以实例讲述破解网站的原理及如何进行防护!如何让网站变得更安全。
web安全:通俗易懂,以实例讲述破解网站的原理及如何进行防护!如何让网站变得更安全. https://www.cnblogs.com/1996V/p/7458377.html 感谢原作者写的内容 安全 ...
- Laravel渴求式加载(比较容易理解理解load与with关系)
渴求式加载 当以属性方式访问 Eloquent关联关系的时候,关联关系数据是「懒惰式加载」的,这意味着关联关系数据直到第一次访问的时候才被加载.不过,Eloquent 还可以在查询父级模型的同时「渴求 ...
- Eclipse导入工程后出现中文乱码
Eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的.一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果该工程的编码方式与eclipse中设置的编码方式不同 ...