【单选】用归并排序统计逆序对,合并部分的核心代码如下。若把判断条件中的 a[i] <= a[j] 改成 a[i] < a[j],则 ans 统计出的结果( )。
// 归并 a[l..mid] 与 a[mid+1..r],同时累加逆序对
if (a[i] <= a[j]) {
tmp[k++] = a[i++]; // 取左半段元素
}
else {
tmp[k++] = a[j++]; // 取右半段元素
ans += mid - i + 1;
}归并统计逆序对时,a[i] <= a[j] 表示"左边元素不大于右边,不算逆序";改成严格小于后,相等的元素对也被计入,于是答案变成满足 i < j 且 a[i] ≥ a[j] 的数对个数(即"逆序对 + 相等对")。
认为改成 < 后只是"更严格所以更少"(刚好相反,条件变苛刻后统一归入 j 分支,统计值只会不减);或者误以为结果翻倍。
本题考查归并排序统计逆序对时比较符号的影响。
// 合并 a[l..mid] 与 a[mid+1..r],同时累加逆序对
if (a[i] <= a[j]) tmp[k++] = a[i++]; // 取左半段元素
else {
tmp[k++] = a[j++]; // 取右半段元素
ans += mid - i + 1; // 一次性计入"左半剩余元素"个数
}a[i] <= a[j] 的含义当取右半段的 a[j] 时,说明 a[:i] 中所有剩余元素都 > a[j],它们各自与 a[j] 构成一个逆序对(i < j 且 a[i] > a[j]),因此一次加 mid − i + 1 个。此时统计的是严格逆序对:i < j 且 a[i] > a[j]。
a[i] < a[j] 后ans += mid − i + 1 —— 于是相等元素对被算成了"逆序"。所以 ans 统计的集合从 {i<j 且 a[i] > a[j]} 变成 {i<j 且 a[i] ≥ a[j]},即 原来的逆序对 + 所有相等的数对。
答案 C(变为满足 i < j 且 a[i] >= a[j] 的数对个数)。
数组 [2, 2]:
<=,统计"非逆序"(≥ 的数对)用 < —— 符号方向极易记反,判断时抓一句:"等号跟着哪个分支,那个分支就不计数";<= 保证稳定,< 会破坏稳定性。