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区间 ...
随机推荐
- MySQL索引操作
创建普通索引 CREATE INDEX index_name ON table_name(column1,column2); 另一种建立方式: ALTER TABLE table_name ADD I ...
- ThinkPHP框架整合phpqrcode生成二维码DEMO
ThinkPHP框架发展到今天功能已经变得是非常强大了,但是ThinkPHP框架中没有二维码相关的库,因此我们可以通过整合phpqrcode来完成生成二维码的功能.想使用phpqrcode首先就要把p ...
- 随机函数rand()和srand()
C++中随机函数rand()和srand()的用法 一.rand() 函数名: rand 功 能: 随机数发生器 用 法: int rand(void); 所在头文件: ...
- aview安装和使用
一.安装aalibwget https://sourceforge.net/projects/aa-project/files/latest/download?source=files --no-ch ...
- Modbus库开发笔记:Modbus ASCII Slave开发
与Modbus RTU在串行链路上分为Slave和Master一样,Modbus ASCII也分为Slave和Master,这一节我们就来开发Slave.对于Modbus ASCII从站来说,需要实现 ...
- STM32L476应用开发之八:便携式气体分析仪项目总结
在本次项目中,我们实现的实际上是2套设备:便携式氧气分析仪以及便携式甲烷分析仪.但这两台仪器实际使用的主控板我们是设计了一套,所以主控板是适合于这两个设备的. 1.硬件设计 便携式气体分析仪的功能比较 ...
- 后RCNN时代的物体检测及实例分割进展
https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650736740&idx=3&sn=cdce446703e69b ...
- day03 变量 运算符 基本数据类型 输出功能 格式化输出
变量补充 变量的命名 1变量名的命名的大前提:应该能够反映出变量值所记录的状态 具体的1.变量名由字母数字下划线组成 2.不能以数字开头 3.不能使用关键字命名为变量名 两种写法 1.驼峰体(由字母组 ...
- anaconda利用pip安装module
开始_程序 中搜索:anaconda prompt (控制台) 输入pip 出现pip的一些信息,可以忽略 接着输入 pip install 模块名称 例如:pip install alphalens ...
- Allegro PCB Design GXL (legacy) 从dxf文件中导入板框
Allegro PCB Design GXL (legacy) version 16.6-2015 新建brd文件,并设置好相应的参数之后,点击菜单:File > Import > DXF ...