逆序对的数量
2023-12-13 12:08:35
//采用归并排序,归并的过程可以算出逆序对的个数
//所有的逆序对个数 =
/*
排序后,两个数都在左边的逆序对数
排序后,两个数都在右边的逆序对数
如果一个数在左边,一个数在右边,在归并的过程中
*/
//左边 <= 右边,正常归并。如果左边 > 右边
//那么左边往右的所有数都可以和右边的第一个数构成逆序对
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main{
static int n;
static final int N = 100010;
static int[] a = new int[N];
static int[] t = new int[N];
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args)throws IOException {
n = Integer.parseInt(in.readLine());
String[] data = in.readLine().split(" ");
//读取数据
for (int i = 0; i < n; i++) a[i] = Integer.parseInt(data[i]);
//调用归并排序得到结果
long res = merge_sort(a,0,n - 1);
System.out.println(res);
in.close();
}
public static long merge_sort(int a[],int l,int r){
//分治结束条件
if (l >= r) return 0;
long res = 0;
int mid = l + r >> 1;
res = merge_sort(a,l,mid) + merge_sort(a,mid + 1,r);
//归并算最终结果,当a[i] > a[j] 时要特殊处理
int k = 0,i = l,j = mid + 1;
while (i <= mid && j <= r){
if (a[i] <= a[j]) t[k++] = a[i++];
else {
t[k++] = a[j++];
//相当于计算[i,mid]之间有多少个数
res += mid - i + 1;
}
}
//剩余的数直接放入即可
while (i <= mid) t[k++] = a[i++];
while (j <= r) t[k++] = a[j++];
//最后将排序的数还给a[]
for(i = l,j = 0;i <= r;i++,j++) a[i] = t[j];
return res;
}
}
文章来源:https://blog.csdn.net/2302_76649176/article/details/134897214
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!