APIO2019简要题解
Preface
由于一些奇妙的原因,我们学校所有人今年都没去\(APIO\),所以就抽空把今年的题做了一下 好像咕了很久了
桥梁
Description
给定一个\(n\)个点\(m\)条边的带权无向图,你需要支持两种操作
- 修改一条边的边权
- 询问从一个点开始,只能经过不低于某个权值的边,能够到达多少个点
\(n \leq 5 \times 10^4, m, q \leq 10^5\)
Solution
由于该问题是一个在图上的较复杂并且带修的问题,所以我们可以考虑如何分块去做
我们可以对于询问按时间分块,然后对于前缀块和当前块都按照权值从大到小排序,然后我们就不断地把前缀块中大于当前询问权值的边加入到并查集内。然后枚举当前块中的修改操作,如果其当前询问的时刻权值大于当前询问的权值,也要加入并查集,注意在当前询问结束的时候要撤销掉当前块中的修改操作
嘴巴一时爽,实现火葬场
奇怪装置
Description
对于任意一个时刻\(t\)对应着一个二元组\(((t + \lfloor\frac{t}{B}\rfloor) \bmod A, t \bmod B)\),其中\(A, B\)是给定的参数
给定\(n\)个时间段\([l_i, r_i]\),问对于所有位于时间段中的时刻一共有多少种不同的二元组
\(n \leq 10^6, 0 \leq l_i \leq r_i \leq 10^{18}\)
Solution
我们可以考虑设这个二元组的循环节为\(k\),不难列出同余方程组
由\((2)\)式得,\(k\)为\(B\)的倍数,所以我们可以对\((1)\)式化简
根据同余方程的基本运算法则,我们可以对其继续化简
所以其最小循环节就是\(\dfrac{AB}{(A, B + 1)}\),所以我们就需要对于所有给定的区间在模循环节的意义下做区间覆盖就可以了
路灯
Description
有一个长度为\(n\)的路段,路段的端点从\(1\)到\(n + 1\)标号,其中有些路段是可以经过的,你需要支持两种操作
- 改变一个路段的状态,即如果本来可以经过,就变成不能经过,反之亦然
- 询问从\(0\)时刻开始到当前时刻,一共有多少个时刻满足出租车能从端点\(a\)到端点\(b\)
\(n, q \leq 3 \times 10^5\)
Solution
我们可以考虑用一个\(set\)来维护断点,这样就可以快速查询每个位置极左/右能够到达的位置。然后我们可以把每一个询问看成二维平面上的一个点,那么一个修改操作影响的就是一个矩形区间,所以就相当于是要求一个历史版本和。但是,由于这道题修改的权值都是一样的,所以我们就可以每次把当前时刻到结束时刻的贡献都算上去,最后查询的时候再判断一下当前是否联通的就可以了。所以就转化为了一个矩形加,单点查询的问题,所以就直接\(CDQ\)分治就可以了