The Number of Inversions(逆序数)

Posted hh13579

tags:

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

For a given sequence A={a0,a1,...an1}A={a0,a1,...an−1}, the number of pairs (i,j)(i,j) where ai>ajai>aj and i<ji<j, is called the number of inversions. The number of inversions is equal to the number of swaps of Bubble Sort defined in the following program:

bubbleSort(A)
  cnt = 0 // the number of inversions
  for i = 0 to A.length-1
    for j = A.length-1 downto i+1
      if A[j] < A[j-1]
	swap(A[j], A[j-1])
	cnt++

  return cnt

For the given sequence AA, print the number of inversions of AA. Note that you should not use the above program, which brings Time Limit Exceeded.

Input

In the first line, an integer nn, the number of elements in AA, is given. In the second line, the elements aiai (i=0,1,..n1i=0,1,..n−1) are given separated by space characters.

output

Print the number of inversions in a line.

Constraints

  • 1n200,0001≤n≤200,000
  • 0ai1090≤ai≤109
  • aiai are all different

Sample Input 1

5
3 5 2 1 4

Sample Output 1

6

Sample Input 2

3
3 1 2

Sample Output 2

2

已知逆序数等于冒泡排序的序列,但这题冒泡排序肯定超时。这题用归并排序优化一下就行。

AC代码

#include<iostream>
#include<cstring>
#include<stack>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAX 500000
#define INF 2e9
int L[MAX/2+2],R[MAX/2+2];
long long  cnt=0;
long long merge(int A[],int n,int left,int mid,int right)
{
    long long cnt=0;
    int n1=mid-left;
    int n2=right-mid;
    for(int i=0;i<n1;i++)
    {
        L[i]=A[left+i];
    }
    for(int i=0;i<n2;i++)
    {
        R[i]=A[mid+i];
    }
    L[n1]=INF;
    R[n2]=INF;
    int i=0,j=0;
    for(int k=left;k<right;k++)//合并
    {
     if(L[i]<=R[j])
     A[k]=L[i++];
     else
     {
     A[k]=R[j++];
     cnt=cnt+(n1-i);
}
}
return cnt;
}
long long  mergeSort(int A[],int n,int left,int right)
{
    long long v1,v2,v3;
    if(left+1<right)
    {
        int mid=(left+right)/2;
        v1=mergeSort(A,n,left,mid);
        v2=mergeSort(A,n,mid,right);
        v3=merge(A,n,left,mid,right); 
        return (v1+v2+v3); 
    }
    else
    return 0;
}
int main()
{
int A[MAX],n;
cnt=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>A[i];
cnt=mergeSort(A,n,0,n);
cout<<cnt<<endl;
return 0;
 }

 

 

以上是关于The Number of Inversions(逆序数)的主要内容,如果未能解决你的问题,请参考以下文章

*Find the Number Occurring Odd Number of Times

[Gym 100228] Graph of Inversions

CF Gym100228Graph of Inversions

number field is the union of the set of all strings and the set of all numbers. The set of things th

NiFi PutKudu错误:the number of replicas does not equal the number of servers解决方案

CodeForces Gym 100228 Graph of Inversions