讲师:PinkRabbit 时间:20210630 地点:福建师大附中
有 亩土地,一开始都是空的,一个农夫要在上面种草。
其中,第 亩土地的草每天会长高 厘米。
农夫一共会进行 次收割,其中第 次收割在第 天,并把所有高度大于等于 的部分全部割去。
输出每次收割得到的草的高度总和。
数据范围:,,。且 ,任意时刻不存在一亩草高度超过 。
倘若每次收割不互相影响呢?我直接按照 排序,二分出高度,然后线段树维护即可。
这时我们发现,即使有收割,它也是单调的,我们依然可以二分。
维护一张无向图,支持加边、删边、询问连通性。
允许离线,数据范围:。
线段树分治模板题,不多解释。下略例题 3、5,因为类似。
给定一棵树, 次询问,给定 ,求 且 时 的最大值。
数据范围:。
考虑单点 到点集 的最远距离,显然把 放大为它的虚树答案不变;众所周知:
一个点到树的最远距离一定在直径端点处取得。
再考虑把 扩大为点集 ,同理,到 端点的最大距离,也是再 的直径端点上取得。
因此,只要找到四个端点,两两组合就能算出答案。
如何计算区间 的最远点对呢?我们可以增量构造,每次在原有直径的基础上进行判断,加上回滚莫队即可。
但是着并不够巧妙。由于有合并的性质,我们直接拿线段树维护这个东西,PushUp
时直接用这个性质进行合并。
在平面直角坐标系中维护两个操作:
1.加入一条线段,编号为 。
2.询问与竖线 相交的线段中,交点最高的线段的编号。
强制在线,数据范围:,,。
如果用李超树的话,复杂度 ,下面介绍一个牛逼方法:D-S 序列
。
考虑加入 个 段的分段函数,那么它的上包络线段数小于等于 ,并且有:
可以看到这个级别是很小的。我们暴力维护顺序维护每一段,显然可以 合并两个包络线。
如果是一并输入的话,我可以分治一下,然后大力合并。
如果是动态输入的话,可以使用二进制分组法,这么做是两个 的。利用分散层叠可以优化掉一个。
题意略。这里将一个重要的衍生方法。
正常的楼房重建,每个区间维护的是这个区间的答案,然后查询的时候向下二分。这么做的话需要可减性。
但是其实可以维护每个右区间对本区间答案的贡献,这样子二分下去做就不需要可减性。
Alice 和 Bob 要竞选总统。
有 个选民,编号为 ,他们中有的人支持 Alice,有的人支持 Bob,还有的人保持中立。
现在你需要把选民分成若干区间,每个区间的长度在 中,如果一个区间中支持 Alice 的人比支持 Bob 的人多,那么 Alice 得一票,如果一个区间中支持 Bob 的人比支持 Alice 的人多,那么 Bob 得一票,如果一个区间中支持 Alice 的人和支持 Bob 的人一样多,那么两人均不得票。
Alice 想要赢得选举,她请你合理地划分区间,使得她获得的票数减去 Bob 获得的票数尽可能大。
数据范围:,保证存在至少一个划分方案。
令支持 Alice 为 ,Bob 为 ,记录前缀和为 ,则:
维护中,对于每个 建一个单调队列,每次都扔进去,并且记一下;弹出的时候,一次必然只会弹出一个;然后用线段树维护一下单调队列队首元素的区间最值,即可。
给定一棵树,点权有正有负。
执行 次修改点权的操作,每次操作后询问连通块点权之和的最大值。
数据范围:。
DDP
写矩阵的最好方法是:假设是静态、链上的问题,于是有方程:
然后因为链上和树上的方程实质上是等价的,于是就列完了。所以考虑链上问题是解决 DDP
的一个好方法。
每次修改中,先单点修改,然后再单点修改此轻链链顶的父亲,依次类推……
给定一个长为 的数组 。
有 个操作,编号为 ,每个操作形如把区间 内的数置为这个区间的最大值。有 次操作:
1.给定 ,修改 。
2.给定 ,询问如果依次执行编号为 的操作, 将会是多少。
数据范围:。
显然每个点对应一个区间的最值,而具体 是什么数其实很好维护,难的是怎么找到对应的区间。
这时有一个重要的事情:考虑从 操作反推到 操作,这样就只需要维护单个 就行了;而顺推需要维护所有的点的 。
并且我们发现 和 是相互独立的,因此我们直接分别倍增维护。记 为在 操作处向左有效的 步, 会从 移动到哪里。注意,一定是要找有效的步骤,即 的步骤,不然就不能保证 。
给定一棵 个结点的树,每条边有正整数权值。
求出 ()从小到大排序后的前 个值。
数据范围:,。
直接超级钢琴套点分树即可辣!
给定一个长度为 的数列 。
有 次操作,每次要么修改数列某一项,要么给出 ,询问区间 中的数从小到大排序后能否形成公差为 的等差数列。
强制在线。数据范围:,。
只要判断三个条件,差分的 、极差为 、没有重复的数( 除外)。
给定一个长度为 的排列。
有 次询问,每次给定一个区间,求这个区间的所有是连续段的子区间个数。
连续段的定义是排序后形成公差为 的等差数列。
数据范围:。
考虑 时怎么做?直接从左往右扫,结合两个单调栈来维护 ,并且查询最小值个数。
那么结合上区间,直接在扫描到 时查询一下 的历史最小值和历史最小值个数,这时吉老师线段树的问题。
给定一棵 个结点的有根树,每个点有正整数权值 。
对于每个点,输出它的子树中有多少个点的权值与它的权值互质。
数据范围:,。
先反演一波——
注意到 的性质,只需要处理 种 即可;考虑如何维护 ,既然不能线段树合并啥的,那就只能考虑做差法,进入子树的时候算一次,出子树的时候算一次;加入一个数的复杂度是 的。
给定一棵 个结点的树,每个点有点权。
有 次询问,每次给定 ,表示从 出发每次朝 方向跳 条边的距离,如果当前点和 距离不超过 就直接一步跳到 ,请求出经过的所有点的点权和。
数据范围:。
分治一下, 直接暴力跳; 的预处理一下。
考虑怎么在 时间内完成预处理——这里有一个小 Trick
:到每个点,用栈把它到根的链记录下来,然后对每个 都分别计算;查询时,我先算出 LCA
,并在 的时间内从 LCA
往上跳,跳到一个深度与 点关于 同余的点,算出点权和;在 上方 个点中也暴力找到与前边同于的点,同理再算出第二条链上的点权和。
给定一张有 个结点 条边的无向图。
有 次询问,每次给定一些边和一些点,询问在原图基础上加入这些边后,这些点是否在同一个边双连通分量中。
数据范围:,询问时添加的边数和询问的结点数之和分别不超过 。
当然是先缩点,建出由新边端点和询问点组成的虚树,然后将这颗虚树拿去 Tarjan
即可。