逆序对的数量(归并排序求解)

给定一个长度为n的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序对;否则不是。

输入格式

第一行包含整数n,表示数列的长度。

第二行包含 n 个整数,表示整个数列。

输出格式

输出一个整数,表示逆序对的个数。

数据范围

1≤n≤1000001≤n≤100000

输入样例:

6
2 3 4 5 6 1

输出样例:

5
import java.util.Scanner;

public class Main {
         static long cnt=0;
         static int b[]=new int[100005];
         static int a[]=new int[100005];
         public static void merge_sort(int a[],int l,int r){
               if(l>=r) return;
               int mid=l+r>>1;
               merge_sort(a,l,mid);
               merge_sort(a,mid+1,r);
               int k=l,i=l,j=mid+1;
               while(i<=mid&&j<=r){
                     if(a[i]>a[j]){
                           b[k++]=a[j++];
                           cnt+=(mid-i+1);
                     }
                     else b[k++]=a[i++];
               }
               while(i<=mid) b[k++]=a[i++];
               while(j<=r) b[k++]=a[j++];
               for(int t=l;t<=r;t++) a[t]=b[t];
         }
         public static void main(String[] args) {
              Scanner scan=new Scanner(System.in);
              int n=scan.nextInt();
              for(int i=0;i<n;i++) a[i]=scan.nextInt();
              merge_sort(a,0,n-1);
              System.out.println(cnt);
        }
}

原文地址:https://www.cnblogs.com/qdu-lkc/p/12184728.html

时间: 2024-10-21 12:42:08

逆序对的数量(归并排序求解)的相关文章

[算法导论]练习2-4.d求排列中逆序对的数量

题目:给出一个确定在n个不同元素的任何排列中逆序对数量的算法,最坏情况需要Θ(nlgn)时间.(提示:修改归并排序.) 思路:修改从大到小排序的归并排序. 归并排序分为三步:分解.解决.合并. 分解:将排列A分解为A1.A2两个子排列. 解决:递归的从大到小排列A1和A2,在此同样递归的求解A1.A2的逆序对数量. 合并:按照递归排序的合并策略从大到小比较A1中的元素[a1,a2,a3…]和A2中的元素[b1,b2,b3…]. 1.若a1大于b1,则a1大于A2中的所有元素,逆序对的数量加上le

算法学习——利用归并排序求逆序对的数量

首先明白逆序对的定义,逆序对就是数组中两个元素前大后小,我们就称这两个元素为一组逆序对. 接着看题目:  我们利用分治的思想,将区间一分为二,然后得到了逆序对的存在情况共三种: 1.两个元素都在左侧区间. 2.两个元素都在右侧区间. 3.两个元素一个在左,一个在右. 那么很明显我们分治的去解决这个问题,就得到解法, 1.将区间划分成左右两个区间 2.递归左右两个区间 3.统计逆序对数量(1)+(2) 4.计算逆序对数量(3) 5.返回相应的结果. 那么问题来了,逆序对(1)(2)的情况都很容易理

洛谷 P1908 逆序对 Label:归并排序||树状数组

题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对.知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目. 输入输出格式 输入格式: 第一行,一个数n,表示序列中有n个数. 第二行n个数,表示给定的序列. 输出格式: 给定序列中逆序对的数目. 输入输出样例 输

【SGU 180】Inversions —— 归并排序或树形数组计算逆序对

原题链接 180. Inversions time limit per test: 0.25 sec. memory limit per test: 4096 KB input: standard output: standard There are N integers (1<=N<=65537) A1, A2,.. AN (0<=Ai<=10^9). You need to find amount of such pairs (i, j) that 1<=i<j&l

求逆序对(inversion)的个数

2-4 逆序对 设A[1...n]是一个包含n个不同数的数组,如果在i<j的情况下,有A[i]>A[j],则(i,j)就称为A中的一个逆序对(inversion). a)列出数组<2, 3, 8, 6, 1>的5个逆序对 b)如果数组的元素取自集合{1,2,...,n}, 那么, 怎样的数组含有最多的逆序对?它包含多少个逆序对? c)插入排序的运行时间与输入数组中逆序对的数量之间有怎样的关系?说明你的理由. d)给出一个算法,它能用Θ(nlgn)的最坏情况运行时间,确定n个元素的任

【算法32】计算数组中的逆序对

问题描述 设 A[1...n] 是一个数组,如果对于 i < j 有 A[i] > A[j], 则 A[i] 和 A[j] 构成一对逆序.给定一个数组,计算数组中逆序对的个数.例如数组 a[] = {1, 4, 3, 2}, 则 {4, 3} {4, 2} {3, 2}是逆序对,返回 3. 解法一:暴力求解 两个 for 循环枚举所有的数对,如果是逆序对,则 count++,最终返回 count 即可.时间复杂度 O(n^2),代码如下: 1 #include <iostream>

逆序对问题---求逆序数

逆序数:在一个排列中,如果一对数的前后位置与大小顺序相反, 即前面的数大于后面的数,那么它们就称为一个逆序. 一个排列中逆序的总数就称为这个排列的逆序数.逆序数为偶数的排列称为偶排列:逆序数为奇数的排列称为奇排列. { 设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同. 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这一个有序对称为 A 的一个逆序对,也称作逆序.逆序对的数量称作逆

分治法求逆序对数目

设A[1..n]是一个包含n个不同整数的数组.如果在i<j的情况下,有A[i]>A[j],则(i,j)就称为A中的一个逆序对(inversion). 给出一个算法,确定n个元素的任何排列中逆序对的书目.时间复杂度为o(nlgn). 分治法求解思路: 分解:将数组A[1..n]分为两个子序列A[1..p]和A[p+1,n],二分法将其分解.. 解决:根据归并排序的思想,在合并过程中,计算逆序对.假如两个子序列为X={4,5}和Y={2,3},则XY的逆序对为X中元素大于Y中元素的数目. 合并:对

O(n*lgn)时间复杂度的逆序对统计算法实现思想

逆序对定义:设A[1..n]是一个包含n个不同数的数组.如果在i<j的情况下,有A[i] > A[j],则(i,j)就称为A中的一个逆序对(inversion). 现给出一个算法,其可以用O(n*lgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数量. 简单的算法实现思想:我们可以单纯的通过从前往后的逐一比对来确定逆序对的数量,虽然实现简单,但这样一来时间复杂度将会上升为O(n*n),不符合我们的要求. 改进的算法实现思想:众所周知归并排序的时间复杂度为O(cn*lgn + cn),