前言:
(分块 / 思维) 好题。
思路详解:
由于本题数据范围较小,一眼 O(nm)O(nm)O(nm) 可过,感觉其他的题解都做复杂了。
solution1:
首先用树状数组或者是归并排序算出还没有做修改的数组的逆序对,这是个板子题,不会的建议先学习逆序对模板。
求完之后,考虑如何处理修改操作,事实上,对于单个的修改操作,可以容纳 O(n)O(n)O(n) 的复杂度(虽然性能很差,但是好些呀)。首先,将交换 ai,bia_i, b_iai,bi 两个数本身产生的逆序对数量更新到答案中,然后考虑 (ai+1)∼(bi−1)(a_i + 1) \sim (b_i - 1)(ai+1)∼(bi−1) 中的所有数能产生那些贡献,就是对于这中间的每个数,考虑 ai,bia_i, b_iai,bi 交换后会如何影响贡献,具体来说就是看遍历到的 hih_ihi 看它和 ai,bia_i, b_iai,bi 的大小关系,动态更新的答案即可。
这一段的代码如下:
if (a[i] > a[l]) {
ans++;
} else if (a[i] < a[l]) {
ans--;
}
if (a[i] < a[r]) {
ans++;
} else if (a[i] > a[r]) {
ans--;
}
solution2:
上面的做法时间复杂度有点高,尽管 n×m≤4×107n \times m \le 4 \times 10^7n×m≤4×107,在现在的机子上跑没有压力,但是我们要懂得精益求精,考虑如何优化:
注意到上面的部分其实就是在让 a(l+1)∼(r−1)a_{(l + 1) \sim (r -1)}a(l+1)∼(r−1) 与 al,ara_l, a_ral,ar 比大小,然后更新答案,所以考虑分块优化,然后就很简单了(分块优化模板,应该很好理解)。
时间复杂度对比:
暴力版时间复杂度:O(nm)O(nm)O(nm)。
优化版时间复杂度:O(mn)O(m \sqrt n)O(mn)。
如果您觉得这篇题解对您有帮助的话,不妨点个赞加收藏再走吧!