zoukankan      html  css  js  c++  java
  • 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;
     }
     
  • 相关阅读:
    3个同一行div的摆放div
    Android 项目开发
    iOS 8
    iOS 8
    __FILE__ 与 $_SERVER['SCRIPT_FILENAME']的区别
    高德百度坐标系转换方法
    高德百度坐标系转换方法
    在iOS开发中使用icon font的方法
    在iOS开发中使用icon font的方法
    UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
  • 原文地址:https://www.cnblogs.com/hh13579/p/10859434.html
Copyright © 2011-2022 走看看