A. island
对于正负不同的情况,(O(n)) 枚举左侧的位置然后计算。
对于正负性相同的情况,把笛卡尔树建出来,然后每次考虑跨过最小值的贡献。
分几种情况:左右均不超过最小值,左右仅有一个超过最小值,左右都超过最小值。
然后顺便统计上其中一个端点为划分点的贡献。然后疯狂的写式子拆式子就没了。
做法挺简单的,但是写起来非常恶心。
B. river
容易想到一个 (O(nm)) 的同余系最短路。
然后可以发现一个很好的性质是,这个玩意可以不断花费时间 (1) 达到后一个状态。
这也就是说其实贪心的每次都走最短就行了。
所以预处理出 (w_i) 表示 (time equiv i pmod m) 的情况下花费的最小时间。
然后就可以 (O(n)) 做了,容易发现这个玩意是有环的,所以对于大环直接跳,剩余的部分接着暴力,复杂度就是 (O(m)) 的了。
C. cac
大概可以想到圆方树。然后圆方树还就非常完美的吻合了这个题。
当只经过环上一个点的时候,这个环上的其他点是不能产生贡献的。
当经过环上超过一个点,环上的所有点都要做一次贡献。
然后经过环上超过一个点就恰好对应着圆方树中经过代表一个环的方点。
所以我们把贡献记在方点上,每次修改就把路径上的所有方点累加权值。
每次询问就查询父亲这个方点的权值和。
但是这样做有一些小问题,(lca) 处有一些特殊的情况。
对于修改操作,若 (lca) 为圆点,那么 (lca) 这个点应该也累加一次权值。
若 (lca) 为方点,那么 (lca) 的父亲这个圆点不能统计儿子的贡献,所以给 (lca) 的父亲累加一次权值。
考试的时候主要卡在了对于一个圆点怎么找到邻接的所有方点的权值和。
但是这是一个树形结构,所以每个点仅有一个父亲,利用这个性质可以直接给父亲累加权值。