好点对的个数是\(O(n)\)的,而且我们可以 \(O(n)\) 地求出所有好点对。
我们把这些点对以右端点为关键字从小到大排序,再弄个扫描线,每次把右端点在扫描线上的点对的左端点加入线段树,于是我们可以得出右端点小于等于当前时刻 \(t\) 的左端点为 \(i(i \le t)\) 的 好点对的个数。
由于强制在线,我们就可以弄一棵可持久化线段树记录每个时刻的状态。
于是就 \(O(n\log n)\) 预处理,每次询问 \(O(\log n)\) 了。
时空复杂度均为 \(O(n\log n)\)。
刚刚提到了:好点对个数是 \(O(n)\) 的。为什么呢?
我们可以从前往后维护一个单调递减的栈,每当一个元素出栈的时候都说明这个出栈的元素与当前扫到的元素中间没有不比他们小的元素,也就是说他们是好点对。
然后我们注意到:我们在把当前扫到的元素加入栈后,如果栈中有 \(\ge 2\) 个元素的话,就说明这个元素与栈的第二个元素可能是好点对。
所以我们可以用一个单调栈求出所有好点对并且好点对的数量是 \(O(n)\) 的。