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
    题意就是求一组数的逆序数,大小等于冒泡排序交换的次数,但看数据范围,这题用冒泡肯定超时。所以用归并排序模拟冒泡即可。
    #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;
     }
  • 相关阅读:
    0607pm克隆&引用类&加载类&面向对象串讲&函数重载
    0607am抽象类&接口&析构方法&tostring&小知识点
    静态
    面向对象--继承和多态
    面向对象的三个特性:封装
    ALV可输入状态下输入金额字段变小数的问题
    退出程序是跳过屏幕自检 比如 必输 EXIT-COMMAND
    ALV的报表对用户定义格式的控制(ALV I_SAVE)
    获利能力分析COPA的BAPI:BAPI_COPAACTUALS_POSTCOSTDATA 通过增强返回凭证号
    一个使用CDS VIEW 的 DEMO
  • 原文地址:https://www.cnblogs.com/hh13579/p/10833392.html
Copyright © 2011-2022 走看看