问题求解II-HW01 题解
Problem A: 排序
- 给定 $n$ 个整数,输出排序后的结果。
- $n\leq 1000$。
关于排序,我们强烈建议大家学会快速排序和归并排序两种做法。关于快速排序,其思想虽然不那么复杂,但要写出一个对于各种输入都足够高效的版本仍十分有挑战性 (尤其当输入中有大量重复数时),建议大家利用 这道题目 检测自己的快速排序写法是否合格。
Problem B: 逆序对
- 给定一个 $n$ 个数的序列,求逆序对个数。
- $n\leq 2\times 10^5$。
求逆序对有非常经典的基于归并排序的做法。设 $solve(l, r)$ 为 $a_l\cdots a_r$ 中逆序对的个数,计算方法如下:令 $mid=(l+r)/2$,:
- 递归计算 $solve(l, mid)$ 和 $solve(mid+1, r)$。
- 考虑 $[l, mid]$ 里的数对 $[mid+1, r]$ 里的数的贡献。在两个子区间都排好序的情况下,我们只需要对左子区间的每个数计算右边有多少个数比它小即可,这可以通过 $O(n)$ 的一边扫描做到。
由主定理可知,该做法的时间复杂度为 $O(n\log n)$。
CDQ分治
CDQ分治是一类特别的分治技巧,它的框架是:在解决 $[l, r]$ 上的问题时,先递归解决 $[l, mid]$ 和 $[mid+1, r]$,再考虑左侧区间对右侧区间的影响。求逆序对背后的二维偏序是CDQ分治最典型的应用之一,如果你感兴趣,可以参考 这篇文章。