逆序对的数量

归并排序模板题

相关文章

复制代码
//采用归并排序,归并的过程可以算出逆序对的个数

//所有的逆序对个数 = 
                        /*
                        排序后,两个数都在左边的逆序对数
                        排序后,两个数都在右边的逆序对数
                        如果一个数在左边,一个数在右边,在归并的过程中
                        */
//左边 <= 右边,正常归并。如果左边 > 右边
//那么左边往右的所有数都可以和右边的第一个数构成逆序对
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;
    }
}
相关推荐
念越3 小时前
蓝桥杯17届功能测试模拟1期题目及解析(1)
功能测试·蓝桥杯·测试用例·场景法
大阿明3 小时前
Spring Boot(快速上手)
java·spring boot·后端
Liu628883 小时前
C++中的工厂模式高级应用
开发语言·c++·算法
bearpping4 小时前
Java进阶,时间与日期,包装类,正则表达式
java
邵奈一4 小时前
清明纪念·时光信笺——项目运行指南
java·实战·项目
AI科技星4 小时前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
sunwenjian8864 小时前
Java进阶——IO 流
java·开发语言·python
sinat_255487814 小时前
读者、作家 Java集合学习笔记
java·笔记·学习
皮皮林5514 小时前
如何画出一张优秀的架构图?(老鸟必备)
java
百锦再4 小时前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven