题解:CF765F Souvenirs
注意到我们需要处理这个序列上形如 \((a_j,a_i)\) 的点对,因而考虑将询问按右端点离线,并用树状数组存储每个后缀的答案,这样只需对每个 \(i\) 考虑所有的 \(j<i\),然后答案就是 \([l,n]\) 后缀的最小值。
我们首先处理 \(a_j\le a_i\) 的情况(\(a_j\ge a_i\) 同理,或者也可以将值域翻转再做一遍),如果首先按下标 \(j\) 来考虑不太方便。我们按值 \(a_j\) 来处理,假设我们要用一个确定的值 \(v\) 来更新以 \(i\) 为右端点的答案,那么可以离散化 \(a\) 然后用值域线段树找出 \(a\) 为 \(v\) 的点中最大的 \(j<i\),显然我们可以将查询区间扩大到 \([v,a_i]\),这样一定不劣。
但是如果我们每次将 \(v\gets a_j+1\) 的话效率过低,那就要排除一些无意义的位置。发现一定要有 \(a_i-v<v-a_j\),否则一定不优,进一步有 \(2a_i-2v<a_i-a_j\) 和 \(2v>a_i+a_j\),如果令 \(v\gets\lfloor \frac{a_i+a_j}2\rfloor +1\) 来跳的话,每次 \(a_i-v\) 都会减半,因而只会跳 \(O(\log V)\) 次。
这样我们对每个 \(i\) 跳 \(O(\log V)\) 次,每次都要线段树查询以及更新后缀数组的答案,因而总复杂度为 \(O(n\log V\log n)\)。
提交记录:326266764

浙公网安备 33010602011771号