25.09.18
分段
转最大或问题,然后有 \(\mathcal{O}(V\lg V)\) 做法!
具体地,标记每个数的子集,然后对于查询的数进行贪心。
记录到当前位截至时来自被选择数的 1,若查询的数这一位是 0,那么看被选择的数在这一位也为 1 是否被标记。
标记时发现子集都被标记了就可以走了,可以证明复杂度是对的。
删除
入手点是考虑常规区间 dp 会面临拼接出来的新序列如何处理这一问题。
发现如果删了一段,再把两侧合起来删一段,这样删去的整个和表现为 \(kd+2r\)。
然后还可以叠叠乐,删一段 \(kd+nr\)。
那么是否说明 \(kd+nr\) 就可以删呢?否,我如果一个 \(kd+2r\) 和 \(kd+3r\) 两个数靠在一起,显然这俩都不该删。
此时有可能就弃了,但我们尝试继续加限制。
会发现:我们最后一个 \(r\) 是散段拼出来的,而之前在这里面删的段一定拼出了一个合法的 \(kd+(n-1)r\)。
于是任意一个区间就可以看作是 \((l,r,t)\) 的决策,表示覆盖 \(l\sim r\) 这个区间,获得 \(t\) 贡献。
求区间可以做 dp,\(f(l,r,t)\) 表示 \(l\sim r\) 可否拼出 \(kd+tr\)。
直接做背包没啥前途,看看能不能砍下来什么。
然后就会发现 \(f(l,r,t)\) 显然是要包含 \(f(l,r,t-1)\) 这个决策的,虽然它不一定能拼出 \(t-1\),但是 \(t-1\) 可以由它的子集凑出,把它加进去答案不会变优。
于是改设 \(f(l,r)=t\) 为 \(l\sim r\) 最多能拼到 \(kd+tr\),然后直接做就完了。
覆盖
一个显然的贪心是每次找能管尽量多关键点的地方修塔,但它是错的,我不知道为啥。
换个方向,考虑哪些关键点要求比较多,发现中心地带的比较密集,但偏远地带的可能就一次管一个了。
于是考虑那些偏远的关键点,能否和别的的一起弄。
按照深度从下往上处理关键点,那么想要能和其它关键点共用,显然就需要尽量往上修塔,这样和其它点更近。
然后你会发现归纳一下,把每次被管到的点删去,这个东西竟然是对的。
求和
显然当边数足够长的时候,最短路只会在一条边上左右横跳。
那么可以分奇偶讨论,现在只处理奇数条边的最短路。
什么时候会开始左右横跳呢?因为加一条边也可能是偶数条边再往旁边歪一点,最后发现到大概 \(4n+1\) 条边时已经彻底饱满了,只能左右横跳。
这个应该也可以打表猜出。
然后答案的贡献大概就是等差数列求和这样的:对于一条边 \((u,v,w)\) 和其上长为 \(4n+1\) 的路径 \(s\),对于 \(m\) 条边提供的一个可能值是 \(s+w(m-4n-1)\)。
而真正的 \(m\) 条边路径是所有边这个值的 \(\min\),也就是我们要处理一个多个等差数列的 \(\min\) 求和加起来的问题。
显然是算出这些一次函数取 \(\min\) 之后的分段函数,然后每段加起来就行。

浙公网安备 33010602011771号