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