51 Nod 1019 逆序数(归并排序)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51 Nod 1019 逆序数(归并排序)相关的知识,希望对你有一定的参考价值。

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019

题意:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。

如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。
 
题解:逆序数的求法有两种,一种就是在冒泡排序的过程中求得(直接暴力枚举,也就是我们平常O(n^2)级别的求法)还有一种是在归并排序过程中求,这个的时间复杂度就可以降低到O(nlogn)
关于归并排序求逆序数,我举个栗子,一堆为(4 6 7 8),另一堆为(2 6)。我们先把第二堆中2归并进去,在第一堆中找到第一个比它大的数4,然后此时产生的逆序数为len1-i+1=4-1+1=4
同理6产生的逆序数为4-3+1=2。就是这个意思....
归并排序的思想很简单,就是先分开,排下序,然后合并。注意对数据的更新就好了。
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N=50000+10;
 6 typedef long long LL;
 7 
 8 LL cnt;
 9 int num[N],result[N];
10 
11 void merge(int *num,int *result,int start,int end){
12     int t=start,mid=(start+end)/2;
13     int i=start,j=mid+1;
14     while(i<=mid&&j<=end){
15         if(num[i]<=num[j]) result[t++]=num[i++];
16         else if(num[i]>num[j]){
17             result[t++]=num[j++];
18             cnt+=mid-i+1;
19         }
20     }
21     while(i<=mid) result[t++]=num[i++];
22     while(j<=end) result[t++]=num[j++];
23     for(int i=start;i<=end;i++) //更新 
24     num[i]=result[i];
25 }
26 
27 void merge_sort(int *num,int *result,int start,int end){
28     if(end-start==1){
29         if(num[start]>num[end]){
30             int tmp=num[start];
31             num[start]=num[end];
32             num[end]=tmp;
33             cnt++;
34         }
35         return ;
36     }
37     if(end-start==0) return ;
38     merge_sort(num,result,start,(end+start)/2);
39     merge_sort(num,result,(end+start)/2+1,end);
40     merge(num,result,start,end);
41 }
42 
43 int main(){
44     int n;
45     cin>>n;
46     for(int i=1;i<=n;i++) cin>>num[i];
47     merge_sort(num,result,1,n);
48     cout<<cnt<<endl;
49     return 0;
50 }

 

 

以上是关于51 Nod 1019 逆序数(归并排序)的主要内容,如果未能解决你的问题,请参考以下文章

逆序数 51nod 1019 归并 分治

51Nod1019题(逆序数)

51nod 1019 逆序数

51nod1107(逆序对数&归并排序)

51 Nod 1107 斜率小于0的连线数量 (转换为归并求逆序数或者直接树状数组,超级详细题解!!!)

归并排序应用——剑指 Offer 51. 数组中的逆序对