Codeforces 316E3 线段树 + 斐波那切数列 (看题解)
最关键的一点就是
f[ 0 ] * a[ 0 ] + f[ 1 ] * a[ 1 ] + ... + f[ n - 1] * a[ n - 1]
f[ 1 ] * a[ 0 ] + f[ 2 ] * a[ 1 ] + ... + f[ n ] * a[ n - 1]
f[ 2 ] * a[ 0 ] + f[ 3 ] * a[ 1 ] + ... + f[ n + 1] * a[ n - 1]
......
这也是满足斐波那切的性质
也就是说,系数的斐波那切的多项式也能向斐波那切一样递推。
然后我们在线段树上保存系数为f[ 0 ]开始的多项式的值和系数为f[ 1 ]开始的多项式的值。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 2e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); void add(int& a, int b) {
a += b; if(a >= mod) a -= mod;
} int mat[N][][], f[N], g[N]; void print(int o) {
puts("");
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++) {
printf("%d ", mat[o][i][j]);
}
puts("");
}
} #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
int f0[N << ], f1[N << ];
int lazy[N << ]; inline int getVal(int f0, int f1, int k) {
if(k == ) return f0;
else if(k == ) return f1;
else return (1LL * mat[k - ][][] * f1 % mod + 1LL * mat[k - ][][] * f0 % mod) % mod;
}
void pull(int rt, int l, int r) {
int mid = l + r >> ;
f0[rt] = f0[rt << ];
f1[rt] = f1[rt << ];
add(f0[rt], getVal(f0[rt << | ], f1[rt << | ], mid - l + ));
add(f1[rt], getVal(f0[rt << | ], f1[rt << | ], mid - l + ));
}
void push(int rt, int l, int r) {
int mid = l + r >> ;
if(lazy[rt]) {
add(lazy[rt << ], lazy[rt]);
add(lazy[rt << | ], lazy[rt]);
add(f0[rt << ], 1LL * lazy[rt] * f[mid - l] % mod);
add(f0[rt << | ], 1LL * lazy[rt] * f[r - mid - ] % mod);
add(f1[rt << ], 1LL * lazy[rt] * g[mid - l] % mod);
add(f1[rt << | ], 1LL * lazy[rt] * g[r - mid - ] % mod);
lazy[rt] = ;
}
}
void build(int l, int r, int rt) {
if(l == r) {
scanf("%d", &f0[rt]);
f1[rt] = f0[rt];
return;
}
int mid = l + r >> ;
build(lson); build(rson);
pull(rt, l, r);
}
void update(int L, int R, int d, int l, int r, int rt) {
if(r < L || R < l) return;
if(L <= l && r <= R) {
add(f0[rt], 1LL * d * f[r - l] % mod);
add(f1[rt], 1LL * d * g[r - l] % mod);
add(lazy[rt], d);
return ;
}
push(rt, l, r);
int mid = l + r >> ;
update(L, R, d, lson);
update(L, R, d, rson);
pull(rt, l, r);
}
int query(int L, int R, int l, int r, int rt) {
if(r < L || R < l) return ;
if(L <= l && r <= R) return getVal(f0[rt], f1[rt], l - L);
push(rt, l, r);
int mid = l + r >> ;
return (query(L, R, lson) + query(L, R, rson)) % mod;
} int n, m;
int main() {
mat[][][] = ; mat[][][] = ;
mat[][][] = ; mat[][][] = ;
mat[][][] = mat[][][] = ;
mat[][][] = ; mat[][][] = ;
for(int o = ; o < N; o++) {
for(int i = ; i < ; i++)
for(int j = ; j < ; j++)
for(int k = ; k < ; k++)
mat[o][i][j] = (mat[o][i][j] + 1LL * mat[][i][k] * mat[o - ][k][j] % mod) % mod;
}
f[] = f[] = ;
for(int i = ; i < N; i++) f[i] = (f[i - ] + f[i - ]) % mod;
for(int i = ; i < N; i++) add(f[i], f[i - ]);
g[] = , g[] = ;
for(int i = ; i < N; i++) g[i] = (g[i - ] + g[i - ]) % mod;
for(int i = ; i < N; i++) add(g[i], g[i - ]); scanf("%d%d", &n, &m);
build(, n, );
while(m--) {
int op;
scanf("%d", &op);
if(op == ) {
int x, v;
scanf("%d%d", &x, &v);
int ret = query(x, x, , n, );
update(x, x, -ret, , n, );
update(x, x, v, , n, );
} else if(op == ) {
int L, R;
scanf("%d%d", &L, &R);
printf("%d\n", query(L, R, , n, ));
} else {
int L, R, d;
scanf("%d%d%d", &L, &R, &d);
update(L, R, d, , n, );
}
}
return ;
} /*
*/
Codeforces 316E3 线段树 + 斐波那切数列 (看题解)的更多相关文章
- [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 ...
- 【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)
Description 看题戳我 给你一个序列,要求支持区间加斐波那契数列和区间求和.\(~n \leq 3 \times 10 ^ 5, ~fib_1 = fib_2 = 1~\). Solut ...
- python---复杂度、斐波那切数列、汉诺塔
时间复杂度 用来估计算法运行时间的一个式子. 一般来说, 时间复杂度高的算法比复杂度低的算法慢. 常见的时间复杂度: O(1) < O(logn) < O(n) < O( ...
- [莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II
题目大意:给出一个长度为n的数列a. 对于一个询问lj和rj.将a[lj]到a[rj]从小到大排序后并去重.设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk.当中 ...
- Linux环境C语言斐波拉切数列(1,1,2,3,5,8,13,.........)实现
斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一 ...
- 从斐波那契数列看java方法的调用过程
先看斐波那契数列的定义: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为 ...
- (转)从斐波那契数列看Java方法的调用过程
斐波那契数列的定义: 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家列安纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔 ...
- hdu 4983 线段树+斐波那契数
http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 从l到r区间 ...
随机推荐
- 漏洞扫描工具Nessu的安装和简单使用
一.软件介绍Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它.该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库.Nessus不同于传统的漏洞扫描软件,Ness ...
- 前端 ------ 03 body标签中的相关标签
列表标签 <ul>.<ol>.<dl> 表格标签 <table> 表单标签 <form> 一.列表标签 列表标签分为三种. 1.无序列表&l ...
- 轻松搞懂elasticsearch概念
本文主要介绍elasticsearch6.0的一些基本概念,有助于深入理解.研究elasticsearch和elk系统 一图胜千言 elasticsearch与mysql参照来看 添加一条数据 紫 ...
- Linux 的 OOM 终结者(Out Of Memory killer)
现在是早晨6点钟.已经醒来的我正在总结到底是什么事情使得我的起床闹铃提前了这么多.故事刚开始的时候,手机铃声恰好停止.又困又烦躁的我看了下手机,看看是不是我自己疯了把闹钟调得这么早,居然是早晨5点.然 ...
- Confluence 6 log4j 日志级别
日志级别 DEBUG - 被设计为用来获得最多的信息和事件,在对应用程序进行调试的时候,这个日志级别通常能够提供最多的有效信息(查看应用程序怎么了) INFO - 有关系统正常运行-计划任务运行,服务 ...
- Java的动手动脑(四)
日期:2018.10.18 星期四 博客期:019 Part1:回答为啥会报错 答案:当然会报错啦!因为平常的编程过程中,系统会对我们写的类自动生成一个默认无参形式的构造方法,类似于C++中的体制!这 ...
- error: js/dist/app.js from UglifyJs Unexpected token: name (Dom7)
What you did I have installed Swiper as normal dependency in my Project and import it to my scripts ...
- Android源码分析二 硬件抽象层(HAL)
一 什么是HAL HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现.借助 HAL,您可以顺利实现相关功能,而不会影响或更改更高级别的系统.HAL 实现会 ...
- 【转载】中文输入法下onKeyPress不能触发的问题
onKeypress---->oninput https://segmentfault.com/a/1190000008820968
- ActiveMQ消息的消费原理
消费端消费消息: 在 初识ActiveMQ 中我提到过,两种方法可以接收消息,一种是使用同步阻塞的ActiveMQMessageConsumer#receive方法.另一种是使用消息监听器Messag ...