🤠 参考链接
🤠 归并求逆序对(分而治之)
static int N = 100010;
static int[] q = new int[N], tmp = new int[N];
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++)
q[i] = sc.nextInt();
System.out.println(mergeSort(0, n - 1));
}
/**
* @param l 区间左边界
* @param r 区间右边界
* @return long 类型的区间内的逆序对
*/
private static long mergeSort(int l, int r)
{
// 递归出口
if (l >= r)
return 0;// 区间只有一个数了,没有逆序队
// 分
int mid = l + r >> 1;
long res = mergeSort(l, mid) + mergeSort(mid + 1, r);
// 治 (归并)
int k = 0;// 临时数组指针
int i = l;// 左区间指针
int j = mid + 1;// 右区间指针
while (i <= mid && j <= r)
{
if (q[i] <= q[j])// 无逆序对
tmp[k++] = q[i++];
else
{// 右边区间的数比左边区间的数小,有逆序对
tmp[k++] = q[j++];
res += mid - i + 1;
}
}
// 断后
if (i <= mid)
tmp[k++] = q[i++];
if (j <= r)
tmp[k++] = q[j++];
// 物归原主
for (i = l, j = 0; i <= r; i++, j++)
{
q[i] = tmp[j];
}
return res;
}