程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 2299 Ultra-QuickSort (歸並排序求逆序數)

POJ 2299 Ultra-QuickSort (歸並排序求逆序數)

編輯:C++入門知識

POJ 2299 Ultra-QuickSort (歸並排序求逆序數)


 

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 47235   Accepted: 17258

 

Description

\In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,

Ultra-QuickSort produces the output
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

Source

Waterloo local 2005.02.05

題目鏈接:http://poj.org/problem?id=2299

題目大意:求逆序數

題目分析:以前學的用樹狀數組求逆序數,補一下歸並排序的求法,感覺實現起來更簡單,歸並排序自頂向下分解,自底向上合並,每次合並的兩個區間都是已經排好序了的,這就給我們求逆序數帶來了很大的好處
我們把一個大區間[l,r]分成[l,mid], [mid + 1, r],顯然每次我們只要求一個數在左區間,一個數在右區間時的逆序數個數,而不用考慮左區間內和右區間內的逆序數個數,因為合並是自底向上的,左區間和右區間內的逆序數我們已經在他們的子狀態中求結果了,所以在自底向上合並時,我們直接累加每一層的逆序數個數就是最後整個區間的逆序數了。很贊的應用,對遞歸有了更深刻的理解


#include 
#include 
#include 
#define ll long long
using namespace std;
int const MAX = 500005;
int a[MAX], n;
ll ans;

void Merge(int l, int mid, int r)
{
    int i = l, j = mid + 1;
    while(i <= mid && j <= r)
    {
        if(a[i] <= a[j])
            i ++;
        else
        {
            j ++;
            //因為左右區間都是有序的,因此a[i]>a[j]說明a[i]~a[mid]都大於a[j]
            ans += mid - i + 1;
        }
    }
    sort(a + l, a + r + 1);
    return;
}

void Merge_sort(int l, int r)
{
    if(l < r)
    {
        int mid = (l + r) / 2;
        Merge_sort(l, mid);
        Merge_sort(mid + 1, r);
        Merge(l, mid, r);
    }
    return;
}

int main()
{
    while(scanf(%d, &n) != EOF && n)
    {
        ans = 0;
        for(int i = 0; i < n; i++)
            scanf(%d, &a[i]);
        Merge_sort(0, n - 1);
        printf(%lld
, ans);
    }
}






 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved