『题解』Codeforces446C DZY Loves Fibonacci Numbers
Portal
Portal1: Codeforces
Portal2: Luogu
Description
In mathematical terms, the sequence \(F_n\) of Fibonacci numbers is defined by the recurrence relation
\]
DZY
loves Fibonacci numbers very much. Today DZY
gives you an array consisting of \(n\) integers: \(a1, a2, \cdots , an\). Moreover, there are \(m\) queries, each query has one of the two types:
Format of the query "
1 l r
". In reply to the query, you need to add \(F_i - l + 1\) to each element ai, where \(l \le i \le r\).Format of the query "
2 l r
". In reply to the query you should output the value of modulo \(1000000009 (10^9 + 9)\).
Help DZY
reply to all the queries.
Input
The first line of the input contains two integers \(n\) and \(m (1 \le n, m \le 300000)\). The second line contains \(n\) integers \(a_1, a_2, \cdots , a_n (1 \le ai \le 10^9)\) — initial array \(a\) .
Then, \(m\) lines follow. A single line describes a single query in the format given in the statement. It is guaranteed that for each query inequality \(1 \le l \le r \le n\) holds.
Output
For each query of the second type, print the value of the sum on a single line.
Sample Input
4 4
1 2 3 4
1 1 4
2 1 4
1 2 4
2 1 3
Sample Output
17
12
Sample Explain
After the first query, \(a = [2, 3, 5, 7]\).
For the second query, \(sum = 2 + 3 + 5 + 7 = 17\).
After the third query, \(a = [2, 4, 6, 9]\).
For the fourth query, \(sum = 2 + 4 + 6 = 12\).
Description in Chinese
题目让我们求给你一个序列,支持区间加Fibonacci
数列前r - l + 1
项和查询区间和。
Solution
一些约定:把斐波那契数列的前两个数\(F_1 = 1, F_2 = 1\)换成另两个数,仍满足\(F_n = F_{n - 1} + F_{n - 2}(n > 2)\)的数列称为广义斐波那契数列。
Fibonacci
数列有一些性质:
性质\(1\). \(F_n = (\sum^{n - 2}_{i = 1}{F_i}) + F_2(n > 2)\);
证明如下:
首先将前几项Fibonacci
数列展开。
F(1) = 1
F(2) = 1
F(3) = F(1) + F(2)
F(4) = F(2) + F(3) = F(2) + F(1) + F(2)
F(5) = F(3) + F(4) = F(3) + F(2) + F(1) + F(2)
F(6) = F(4) + F(5) = F(4) + F(3) + F(2) + F(1) + F(2)
......
在\(F_n = F_{n - 1} + F_{n - 2}\)中,我们可以把\(F_{n - 1}\)按式子展开,可得\(F_n = \sum^{n - 3}_{i = 1} + F_2 + F_{n - 2}\),即\(F_n = (\sum^{n - 2}_{i = 1}{F_i}) + F_2(n > 2)\),跟原式一模一样,故原式正确性得证。
性质\(2\). 一个广义斐波那契数列数列\(f_i\), 当\(f_1 = x, f_2 = y\)时,则有\(f_n = x \times f_{n - 1} + y \times f_{n - 2}\)
证明如下:
这个性质与性质1
类似,证明方法也与性质1
类似,列举几个:
f(1) = x
f(2) = y
f(3) = f(1) + f(2) = x × F(1)
f(4) = f(2) + f(3) = x × F(1) + y × F(2)
f(5) = f(3) + f(4) = x × F(2) + y × F(3)
f(6) = f(4) + f(5) = x × F(3) + y × F(4)
......
把上述规律推广到代数式:
\]
证毕。
性质\(3\): 任意两段不同的广义斐波那契数列段相加(逐项相加),所得的数列任然是广义斐波那契数列。
这个性质易证。
这题我们维护一棵线段树,线段树需要维护\(L\)至\(R\)区间的广义斐波那契数列的第一项,第二项与区间的和。
下传标记时,我们可以在左区间加广义斐波那契数列的前两项,在右区间可以求出总和再加上总和就行了,时间复杂\(\text{O(n log n)}\)。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int MAXN = 300005, MAXM = 1200005, mod = 1e9 + 9;
struct node {
int c1, c2, sum;
} tree[MAXM];
int n, m, opt, x, y, a[MAXN], f[MAXN];
inline int add(int x, int y) {//两项相加并取模
int ret = x + y;
if (ret < 0) return ret += mod; else return ret % mod;
}
inline int calc1(int x, int y, int len) {//计算斐波那契
if (len == 1) return x; else
if (len == 2) return y; else return ((LL)x * f[len - 2] + (LL)y * f[len - 1]) % mod;
}
inline int calc2(int x, int y, int len) {//计算总和
if (len == 1) return x; else
if (len == 2) return add(x, y); else return add(calc1(x, y, len + 2), -y);
}
inline void pushup(int rt) {
tree[rt].sum = add(tree[rt << 1].sum, tree[rt << 1 | 1].sum);
}
inline void pushdown(int rt, int l, int r) {//下传标记
if (tree[rt].c1) {
int mid = l + r >> 1;
tree[rt << 1].c1 = add(tree[rt << 1].c1, tree[rt].c1);
tree[rt << 1].c2 = add(tree[rt << 1].c2, tree[rt].c2);
tree[rt << 1].sum = add(tree[rt << 1].sum, calc2(tree[rt].c1, tree[rt].c2, mid - l + 1));
int x = calc1(tree[rt].c1, tree[rt].c2, mid - l + 2), y = calc1(tree[rt].c1, tree[rt].c2, mid - l + 3);
tree[rt << 1 | 1].c1 = add(tree[rt << 1 | 1].c1, x);
tree[rt << 1 | 1].c2 = add(tree[rt << 1 | 1].c2, y);
tree[rt << 1 | 1].sum = add(tree[rt << 1 | 1].sum, calc2(x, y, r - mid));
tree[rt].c1 = 0; tree[rt].c2 = 0;
}
}
inline void update(int rt, int l, int r, int ansl, int ansr) {//线段树区间更新
if (ansl <= l && r <= ansr) {
tree[rt].c1 = add(tree[rt].c1, f[l - ansl + 1]);
tree[rt].c2 = add(tree[rt].c2, f[l - ansl + 2]);
tree[rt].sum = add(tree[rt].sum, calc2(f[l - ansl + 1], f[l - ansl + 2], r - l + 1));
return ;
}
pushdown(rt, l, r);
int mid = l + r >> 1;
if (ansl <= mid) update(rt << 1, l, mid, ansl, ansr);
if (ansr > mid) update(rt << 1 | 1, mid + 1, r, ansl, ansr);
pushup(rt);
}
inline int query(int rt, int l, int r, int ansl, int ansr) {//线段树区间查询
int ret = 0;
if (ansl <= l && r <= ansr) {
ret = tree[rt].sum;
return ret;
}
pushdown(rt, l, r);
int mid = l + r >> 1;
if (ansl <= mid) ret = add(ret, query(rt << 1, l, mid, ansl, ansr));
if (ansr > mid) ret = add(ret, query(rt << 1 | 1, mid + 1, r, ansl, ansr));
return ret;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
a[i] = add(a[i - 1], x);
}
f[1] = 1; f[2] = 1;
for (int i = 3; i <= n + 2; i++)
f[i] = add(f[i - 1], f[i - 2]);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &opt, &x, &y);
if (opt == 1) update(1, 1, n, x, y); else printf("%d\n", add(query(1, 1, n, x, y), a[y] - a[x - 1]));
}
return 0;
}
『题解』Codeforces446C DZY Loves Fibonacci Numbers的更多相关文章
- Codeforces446C - DZY Loves Fibonacci Numbers
Portal Description 给出一个\(n(n\leq3\times10^5)\)个数的序列,进行\(m(m\leq3\times10^5)\)次操作,操作有两种: 给区间\([L,R]\) ...
- Codeforces446C DZY Loves Fibonacci Numbers(线段树 or 分块?)
第一次看到段更斐波那契数列的,整个人都不会好了.事后看了题解才明白了一些. 首先利用二次剩余的知识,以及一些数列递推式子有下面的 至于怎么解出x^2==5(mod 10^9+9),我就不知道了,但是要 ...
- codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...
- 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 ...
- Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)
题目:DZY Loves Fibonacci Numbers 题意比較简单,不解释了. 尽管官方的题解也是用线段树,但还利用了二次剩余. 可是我没有想到二次剩余,然后写了个感觉非常复杂度的线段树,还是 ...
- 「CF446C」 DZY Loves Fibonacci Numbers
「CF446C」 DZY Loves Fibonacci Numbers 这里提供一种优美的根号分治做法. 首先,我们考虑一种不太一样的暴力.对于一个区间加斐波那契数的操作 \([a,b]\),以及一 ...
- cf446C DZY Loves Fibonacci Numbers
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers
參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K ...
- [CodeForces - 447E] E - DZY Loves Fibonacci Numbers
E DZY Loves Fibonacci Numbers In mathematical terms, the sequence Fn of Fibonacci numbers is define ...
随机推荐
- python编程基础之二十八
装饰器:说白了就是闭包,但是内部函数调用外部变量调用的是函数, 好处:就是在不用修改原函数代码的前提下给函数增加新的功能 装饰器有两种写法 第一种: #被修饰的函数 def say_hello(nam ...
- SQL SERVER 还原误操作导致还原无法停止,处理办法
昨天遇到运行库不知道单位哪个小伙子,把数据库还原了,导致单位业务全部瘫痪,主数据库一直显示正在还原,真的是不敢动,经过多方寻找,找到此脚本-------------------------数据库还原日 ...
- AWD攻防工具脚本汇总(二)
情景五:批量修改ssh密码 拿到官方靶机第一件事改自己机器的ssh密码,当然也可以改别人的密码~ import paramiko import sys ssh_clients = [] timeout ...
- PMBOK(第六版) PMP笔记——《十》第十章(项目沟通管理)
PMBOK(第六版) PMP笔记——<十>第十章(项目沟通管理) 第十章 项目沟通管理: PM 大多数时间都用在与干系人的沟通上. 第十章有三个过程: 规划沟通管理:根据干系人的需求,制定 ...
- [网络流 24 题] luoguP4016 负载平衡问题
[返回网络流 24 题索引] 题目描述 有成环状的 nnn 堆纸牌,现将一张纸牌移动到其邻堆称为一次操作.求使得所有堆纸牌数相等的最少移动次数. Solution 4016\text{Solution ...
- Halcon一日一练:图像设备介绍
Halcon在设计之初就提供了完整的图像采集方案,适应了多种图像设备采集图像,以及各种不同环境的采集方案. 通常情况下,图像的采集应该是所有机器视觉项目首要解决的任务,不幸的是,需要解决图像采集的问题 ...
- Kubernetes WebSSH终端窗口自适应Resize
追求完美不服输的我,一直在与各种问题斗争的路上痛并快乐着 上一篇文章Django实现WebSSH操作Kubernetes Pod最后留了个问题没有解决,那就是terminal内容窗口的大小没有办法调整 ...
- 关于vue使用的一些小经验
这一年来说,vue的势头很猛,用户量“噌”“噌”“噌”的涨 为了不掉队不落伍.在后台大哥的胁迫下,不得不选择用了它 刚开始很难接受vue的写法,在编辑器里很容易报错,基本上每行都会出现红色的波浪线 这 ...
- Linux下yum与apt-get
linux系统基本上分两大类: 1.RedHat系列:Redhat.Centos.Fedora等 2.Debian系列:Debian.Ubuntu等 RedHat 系列 1 常见的安装包格式 rpm包 ...
- 百万年薪python之路 -- MySQL数据库之 完整性约束
MySQL完整性约束 一. 介绍 为了防止不符合规范的数据进入数据库,在用户对数据进行插入.修改.删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数 ...