最关键的一点就是

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 线段树 + 斐波那切数列 (看题解)的更多相关文章

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

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

  2. 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 ...

  3. 【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)

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

  4. python---复杂度、斐波那切数列、汉诺塔

    时间复杂度 ​ 用来估计算法运行时间的一个式子. ​ 一般来说, 时间复杂度高的算法比复杂度低的算法慢. 常见的时间复杂度: ​ O(1) < O(logn) < O(n) < O( ...

  5. [莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II

    题目大意:给出一个长度为n的数列a. 对于一个询问lj和rj.将a[lj]到a[rj]从小到大排序后并去重.设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk.当中 ...

  6. Linux环境C语言斐波拉切数列(1,1,2,3,5,8,13,.........)实现

    斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一 ...

  7. 从斐波那契数列看java方法的调用过程

    先看斐波那契数列的定义: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为 ...

  8. (转)从斐波那契数列看Java方法的调用过程

    斐波那契数列的定义: 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家列安纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔 ...

  9. 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区间 ...

随机推荐

  1. mgo mode说明

    mgo 是 MongoDB 的 Golang 驱动. 连接池 我们通过 Dial 函数创建一个新的 session: session, err := mgo.Dial(url) 创建的 session ...

  2. HTML网页背景图很长要有滚动条滑动

    1 前言 由于网页背景图非常长,然后会出现只显示当前页面,后面部分看不到,也不能滑动,开始以为不能滑动应该是没有加overflow-y: auto(scroll),结果加上去也是无效的. 2 代码 & ...

  3. 进程、线程、GIL、同步、异步、并行、并发、互斥锁

  4. Confluence 6 中样式化字体

    Confluence 提供了通过层叠样式表(CSS)调整页面展示情况的能力.本页面帮助你理解如何在 Confluence 中使用一些 CSS 样式修改字体样式和字体大小. 下面的代码为自定义的字体代码 ...

  5. Java之动手动脑(三)

    日期:2018.10.12 星期五 博客期:017 这次留了两个动手动脑作业!我需要一个一个来说!先说第一个吧! Part 1 :随机生成1000个随机数 代码: //以下为 RandomMaker. ...

  6. LeetCode(123):买卖股票的最佳时机 III

    Hard! 题目描述: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必 ...

  7. laravel PC内部方法调用

    /** * [api 内部请求] * @author Foreach * @param string $method [请求方式] * @param string $url [地址] * @param ...

  8. PDF文件怎么修改,PDF文件编辑方法

    PDF文件是一种独特的文件,在日常办公中已经成为我们使用最广泛的电子文档格式.在使用PDF文件中会遇到PDF文件有错区的时候,再从新制作一个PDF文件会比较麻烦,只能通过工具来对PDF文件进行修改,这 ...

  9. Unity3D料槽设备旋转(一)

    1.使用C#创建控制游戏对象的的脚本语言, 第一步: 在project师徒中create 一个C#脚本,将其按照自己的设备名称进行命名,这里我将其简单的命名成zhuaquanzhou.cs 使用编辑器 ...

  10. bzoj 1042

    典型的背包+容斥 首先,考虑如果没有个数的限制,那么就是一个完全背包,所以先跑一个完全背包,求出没有个数限制的方案数即可 接下来,如果有个数的限制,那么我们就要利用一些容斥的思想:没有1个超过限制的方 ...