//采用归并排序,归并的过程可以算出逆序对的个数
//所有的逆序对个数 =
/*
排序后,两个数都在左边的逆序对数
排序后,两个数都在右边的逆序对数
如果一个数在左边,一个数在右边,在归并的过程中
*/
//左边 <= 右边,正常归并。如果左边 > 右边
//那么左边往右的所有数都可以和右边的第一个数构成逆序对
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;
}
}
逆序对的数量
赚钱给孩子买茅台喝2023-12-11 2:07
相关推荐
测开小菜鸟几秒前
使用python向钉钉群聊发送消息好奇龙猫31 分钟前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】P.H. Infinity1 小时前
【RabbitMQ】04-发送者可靠性生命几十年3万天1 小时前
java的threadlocal为何内存泄漏sp_fyf_20241 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01caridle1 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction^velpro^1 小时前
数据库连接池的创建苹果醋31 小时前
Java8->Java19的初步探索ChoSeitaku1 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)秋の花1 小时前
【JAVA基础】Java集合基础