归并排序查找逆序对

来源:互联网 发布:炒股如何看k线图 知乎 编辑:程序博客网 时间:2024/06/08 03:02

Description

Let A(1), ..., A(n) be a sequence of n numbers. If i<j and A(i)>A(j), then the pair (i,j) is called an inversion pair.

The inversion number of a sequence is one common measure of its sortedness. Given the sequence A, calculate its inversion number.

 

Input

There are multiple cases.

Each case contains an integer n (n<=100,000) followed by A(1) , ..., A(n).

Output

For each case, output the inversion number.

Sample Input
Copy sample input to clipboard
53 1 4 5 2
Sample Output
4

题目分析

根据逆序对的定义,如果暴力比较,复杂度是O(n^2)

采用归并排序的话,可以将复杂度降到O(n*log(n))

假设左右都已经排好序,当右边的某个数i小于了左边的某个数j,

则i一定小于左边部分所有大于j的数,即这些都是逆序对

这样在最终排序完成时,可以找到所有的逆序对

由于归并排序的复杂度为O(n*log(n))

所以总的复杂度为O(n*log(n))


#include <iostream>int arr[100001];long long count;void sort(int start, int end) {  int mid = (start+end) / 2;  int len1 = mid-start+1;  int len2 = end-mid;  int arr1[len1];  for (int i = 0; i < len1; ++i)    arr1[i] = arr[start+i];  int arr2[len2];  for (int i = 0; i < len2; ++i)    arr2[i] = arr[mid+1+i];  int index1 = 0;  int index2 = 0;  for (int i = start; i <= end; ++i) {    if (index1 == len1) {      arr[i] = arr2[index2++];    } else if (index2 == len2) {      arr[i] = arr1[index1++];    } else {      if (arr1[index1] <= arr2[index2]) {        arr[i] = arr1[index1++];      } else {        arr[i] = arr2[index2++];////////////////////////////////////        count += (len1 - index1);////////////////////////////////////      }    }  }}void merge(int start, int end) {  if (start < end) {    int mid = (start+end)/2;    merge(start, mid);    merge(mid+1, end);    sort(start, end);  }}int main(){  int num;  while(std::cin >> num) {    for (int i = 0; i < num; ++i)      std::cin >> arr[i];    count = 0;    merge(0, num-1);    std::cout << count << std::endl;  }}


0 0
原创粉丝点击