题目链接: Physical Education Lessons
大致题意
给定一个长度为 n n n的 01 01 01序列, 有两种操作: 把区间 [ l , r ] [l, r] [l,r]全部变为 1 1 1, 或把区间 [ l , r ] [l, r] [l,r]全部变为 0 0 0.
每次操作结束后, 输出序列中 1 1 1的个数.
解题思路
➡️题目弱化版推荐⬅️
➡️珂朵莉树做法题解⬅️
线段树
我们考虑到如果 n n n比较小(在 1 0 6 10^6 106以内), 我们可以直接用线段树暴力维护区间信息.
但是本题的 n n n很大(有 1 0 9 10^9 109), 我们没法通过堆存储的方式用静态开点线段树来维护. 但是考虑到操作 m m m比较小, 只有 3 ⋅ 1 0 5 3·10^5 3⋅105, 因此涉及到的点个数至多为 2 m 2m 2m. 我们可以采用动态开点的线段树来维护.
但是我们还有一种更节省空间的方式 — 把用到的所有点进行离散化. 但是这样离散化后, 会使得原本不连续的点变得连续, 我们需要再额外插入一些有权值的点, 使得这些点仍然保持不连续.
例如: 如果现在用到的端点有3和7, 离散化后就变成了1和2, 但本身3和7是不挨着的(中间还有4, 5, 6). 但是离散化后, 1和2是挨着的(4, 5, 6这三个点被错误的丢弃了).
因此我们正确的做法是, 在3和7两个点之间再插入一个带有权值的点4, 权值为3(表示4, 5, 6这三个点).
为了便于叙述, 我们不妨把所有的点都看作一个点对 ( x , y ) (x, y) (x,y), 其中

这篇博客介绍了如何使用动态开点线段树解决一个涉及大数(10^9级别)的区间操作问题。在给定的01序列上,可以进行两种操作:将区间内的所有元素置为1或置为0。通过离散化和动态开点线段树,博主展示了如何在操作次数较小(3*10^5)的情况下高效维护区间信息,并给出了AC代码实现。
最低0.47元/天 解锁文章
409

被折叠的 条评论
为什么被折叠?



