AcWing 788. 逆序对的数量(java)
原题链接
简单
作者:
文思涌
,
2021-03-15 11:29:07
,
所有人可见
,
阅读 289
private static int N=100010;
private static int[] arr=new int[N];
//由于最多有100000个数据,最坏情况从大到小,共有n*(n+1)/2个,int最大值是2147483647(10位),结果会超出,得用long
private static long sum;
public static void merge_sort(int l,int r) {
if(l==r)return ;
int mid=l+r>>1;
merge_sort(l, mid);
merge_sort(mid+1, r);
int i=l,j=mid+1;
int[] temp=new int[r-l+1];
int k=0;
while(i<=mid&&j<=r) {
if(arr[i]<=arr[j]) {//注意要小于等于,不等于的话加入arr[j]=arr[i]=5,那会先放入arr[j],但是不符合题意
sum+=j-mid-1;//根据下标j可以计算数组temp放入多少个比arr[i]小的数
temp[k++]=arr[i++];
}else {
temp[k++]=arr[j++];
}
}
//这里不能先在第一个for循环后面,不然可能会改变i值
//若右边全部放进去了,左边还有k个没放,则有k个比右边所有数大,逆序对总数是k*(右边的总数)
sum+=(mid-i+1)*(j-mid-1);
for(;i<=mid;i++)temp[k++]=arr[i];
for(;j<=r;j++)temp[k++]=arr[j];
for(i=l,j=0;i<=r;i++,j++)arr[i]=temp[j];
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
for(int i=0;i<n;i++)
arr[i]=scanner.nextInt();
merge_sort(0, n-1);
System.out.println(sum);
}