线段树分块 Pro Max
关注嘉然喵,关注嘉然谢谢喵。
线段树基础
CF671E
知识点:楼房重建类线段树
我们首先考虑转化一下,这个问题就是
可以写出这个区间的贡献:
接着考虑加
想让前缀和
我们考虑贪心,扫到第一个前缀和小于 0 的位置,对其 +1,含义就是把后面所有点都抬高。但是我们不能放太前面,我们只对于某个
接下来我们就考虑从小到大扫描线,我们枚举一个
- 对于前缀来说:我们用一个
b 记录最大值,我们影响的是后缀代价,也就是r 在这个位置及以后的a_i 需要加上c 。后缀b_i 的值加上c 。 - 对于后缀来说:代价为
\max\limits_{l \leq r} (b_l) - b_r
所以我们可以上线段树!对于第一步我们直接维护,第二步我们不直接维护,设第一个的后缀代价为
里面
我们发现
- 对于
b 区间加 - 查询
\max\limits_{r \geq l}(b_l) - premax_r \leq k 中r 最大值
下面这个问题就是楼房重建类线段树了。
具体来说,我们考虑一个线段树,对于一个区间节点是
那么还有一种情况是大于,那么就不可以预处理了,但是发现左子树里这个前缀和肯定都
对于修改操作,我们的时间复杂度是
「JOISC 2019 Day3」穿越时空 Bitaro
考虑怎么用线段树来维护这个信息,我们可以把所有的开放区间全部减去
如果要经过边
我我们注意到,在一个位置多等一会显然不如少等一会,感性理解就是现在回溯不如以后回溯。
现在就有一个
-
所有区间的交非空,设交为
[l,r] ,我们就直接暴力让当前时间满足条件就行。 -
所有区间的交为空,发现我们出去的时候位置是基本固定的,那么我们总可以认为穿过这段区间的效果是:初始时刻
a ,到达时刻b ,必须使用k 次技能。这是因为我们可以在过区间的时候,将穿过后的一些技能平移到穿过前,这样我们的初始时刻就是相同的;同样也可以将穿过前的平移到穿过后,这样到达时刻就是相同的。
我们把第一类记为 A 点,第二类记为 B 点。B 点我们维护一个三元组
CF1693E
/shui
我们从大往小考虑,对于一个
segbeats
介绍
Segment Tree Beats 学习笔记 - Neal_lee - 博客园 (cnblogs.com)
支持两种操作:
- 区间 check min
- 区间加
我们考虑记录区间中最大值,严格次大值,最大值个数,和。
考虑check min的
c \geq max 无事发生。secmax\leq c \leq max 所有 max 变成 c,sum += (c - mx) * numc \leq secmax 递归两子树,pushup
考虑对复杂度进行势能分析!带区间修改是
void update(int x, int l, int r, int L, int R, int val){
if(t[x].mx <= val) return;
if(l >= L && r <= R && t[x].smx < val){ addtag(x, val); return; }
int mid = (l+r)>>1;
pushdown(x);
if(mid >= L) update(x*2, l, mid, L, R, val);
if(mid < R) update(x*2+1, mid+1, r, L, R, val);
pushup(x);
}
例题 CF1290E
对于每个子树的大小,我们考虑为 i 左侧第一个大于 ai 的位置 - i 左侧第一个大于 ai 的位置 - 1
那么分开来算,我们以第一个为例,第二个是对称的。
从 1-i 来算
线段树分裂
支持三种操作:
- 区间正序排列
- 区间倒序排列
- 区间和
用 treap 维护所有连续段,再用权值线段树维护所有连续段的值
我们每次做区间修改的时候,每次用线段树分裂把当前块分成小块,对于大部块merge。
莫队
“大家都会!”
扫描线
B 维正交范围
在一个 B 维直角坐标系下,第
A-side
理解为前缀。
一维扫描线
用扫描线扫一维,用 DS 维护另一维。
扫过去的过程中会 DS 维护的那一维上产生一些修改和查询。
查询信息可以差分就直接差分(二维数点),否则就需要分治了。
另一个角度就是序列角度,一维扫过去枚举右端点,DS 维护的是左端点答案。个人比较喜欢下面这种表达。
一般来说,能差分的题就尽量差分,问题第一维实际上是降低了自由度,让问题简单了很多!典型的差分方法:
[l,r] 差分为[1,r] - [1,l-1] ,两个前缀和- 树上差分
- 二维前缀和差分
BZOJ3489
这个是一类问题的反演,反演的问题类型:
- 平面上
n 个点,m 次询问矩形内有多少点。 - 平面上
n 个矩形,m 次询问每个点上有多少矩形。
对于这个题就是考虑每个点对哪些区间有贡献,那么就是算每个值对每个区间的贡献。我们称本题询问的这种值称为色数。
我们要维护的实际上是一个 4-side 的矩形。
TEST_73
考虑点连通块就是 点 - 边 的个数。我们考虑边数,边数需要满足三个条件:两个端点,边的编号都在
我们反演一下问题,计算每条边对答案的贡献,得到一个三维问题。发现我们只需要
这题启发是要好好研究问题,否则会造成问题的升维。
BZOJ4212
考虑建 trie,前缀就是 trie 上对应的子树,后缀就是反着建同理。
这个同时的约束,我们把问题拓展到二维,实际上就是查询有多少
子树问题我们可以直接上 DFS 序,就变成一个二维数点了。
UOJ637
这类关于颜色数的问题,我们都考虑利用不同值对答案贡献独立的性质。
对每个元素,我们计算一下它对哪些询问有贡献,然后用DS维护。
我们考虑这个询问被哪些元素不包含。
CometOJ contest14D
还是构造二维平面,一维是操作位置,一维是原来序列的位置。
假设区间对
区间子区间问题
待补
CF526F
转化后题意:给排列,求有多少区间满足
还是想能不能转化成矩形,
掉线了,学弟说可以析合树!
CF997E
我们把
可以看作是一个2-side矩形。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。