CF1495F
decription
给定 \(n\) 和长度为 \(n\) 的排列 \(p\)。在一个位置 \(i\) 可以采取如下行动:
- 
花费 \(a_i\) 走到 \(i+1\)。 
- 
如果 \(p_i\) 后存在一个 \(p_j>p_i\),则可以花费 \(b_i\) 跳到 \(j\),否则可以花费 \(b_i\) 跳到 \(n+1\)。 
希望最小化从 \(1\) 到 \(n+1\) 的花费。此外还有限制:有必经点集合 \(S\),必须经过 \(S\) 内每一个点。
\(m\) 次询问,每次询问的 \(S\) 都是上一次询问的 \(S\) 加上或删除一个元素。每次询问输出最小花费。
- 
\(n,m\leq 2\times 10^5\) 
- 
\(-10^9\leq a_i,b_i \leq 10^9\) 
solution
设 \(S\) 集合是有序的且 \(S_{0}=1,S_{|S|+1}=n+1\)。
第一步转化是求 \(1\) 到 \(n+1\) 的最小花费转化成求 \(S_{i}\) 到 \(S_{i+1}(0\leq i\leq |S|)\) 的花费和的最小值。每一部分是独立的,所以要求每一段的花费的最小值。
每次给集合 \(S\) 加点删点相当于加上或删除共三段的贡献。计算答案的差分数组就可以了(也就是三段最小花费带来的答案变化量)。
问题就变成了有 \(O(m)\) 次询问 \([l,r]\),求 \(l\) 到 \(r\) 的最小花费。
关键的一步是考虑把所有询问离线下来,右端点递增排序。
我们只需要顺次维护 \(1,2,3,\dots n+1\) 位置为终点时它前面的点到它的最小花费。
考虑这个图的性质:设 \(nxt_{i}\) 表示第 \(i\) 个位置下一个比它大的位置(不存在则为 \(n+1\)),那么对于 \(i<j,p_i>p_j\),一定有 \(nxt_{j}\leq nxt_{i}\)。
这说明右端点为 \(r\) 的时候直接加边不会对之前加的边减小的花费造成影响。
直接树状数组维护就行了。
时间复杂度 \(O((n+m)\log n)\)

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号