这题的分治特征比较明显,但是按照传统的二分实现分治大概不可做。
更可做的是对于每个区间的最大值 O(n) 统计答案。
但是这样子复杂度无法保证是 O(nlogn) 的。
可以考虑把单层的复杂度优化到可以接受的范围内,这样即便分治的过程是一条链也只是多了一个 O(n) 而已。
首先,我们把取最大值的过程,用 ST 表优化为 O(1)。
然后,设当前区间 [l,r] 最大值的位置为 mx,那么以 amx 为最大值的数对的答案相当于 mx∑i=lr∑j=mx+1[aj≤amxai],两个 ∑ 的范围交换也一样。
其中 [X] 表示如果 X 成立即为 1 否则为 0。
发现后面这个 ∑ 可以用主席树来做,单次 O(logn)。
现在最大的问题是确定前面这个 ∑ 的取值范围。
非常显然地,我们可以启发式地取两边长度较小的一边来枚举。
这样的话,对于 a 单调的数据,开始提到的那种分治是 O(n2) 的,这个算法反而可以做到 O(nlogn)。
而能够使那种分治的复杂度为 O(nlogn) 的数据反而是这个算法的上界,即 O(nlog2n)。
壮哉我大主席树!
代码:
1 |
|