ARC168F Up-Down Queries

发布时间 2023-11-22 12:00:23作者: Rainbow_qwq

考虑一次询问怎么做:

我们想求的答案就是 每次减时为 \(0\) 的位置个数之和(这些位置会与 \(0\)\(\max\) 从而使答案变大) + \(\sum (m-2\times a_i)\)(所有操作的总和)。

考虑维护 \(y\) 的差分数组,分析一次操作 \([1,x]\)\(1\)\([x+1,m]\)\(1\) 后差分数组的变化:

  • \(x\) 位置的差分 += 2
  • 设差分数组最小有值的位置为 \(t\) ,则 \(t\) 的差分 -= 1
  • 此时 \(\le t\) 的位置为 \(0\) 并且被减,那 \(ans\to ans+t\)

于是暴力算法就是 q.push(x),q.push(x),ans+=q.top(),q.pop(),其中 q 是小根堆。

现在问题转化成了:从左到右,每次加入两个 \(x\),pop 出一个最小的数并加入答案。

这就是 省选d1t3 链的情况,直接套 线段树分治+反悔贪心 or 模拟费用流 的做法。

时间复杂度 \(O(n\log^2 n)\)\(O(n\log n)\)