POJ 2299 Ultra-QuickSort(逆序数、分治)

来源:互联网 发布:温州淘宝城在哪里 编辑:程序博客网 时间:2024/06/01 07:51

Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536KTotal Submissions: 43803 Accepted: 15974

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

59105431230

Sample Output

60

解题报告:根据题意是求交换相邻两位至少需要多少次才能让数组升序。其实就是求逆序数,求逆序数其实和归并排序是一样的,就是在归并的过程中,加入逆序数的统计。例如现在有两个升序数组1 4 9 和 2 6 7 ,那么在归并过程中,插入前一个数组不是逆序,而一旦插入后一个数组中元素,2那么对应的逆序数就加2 。 (因为4和9都还没有插入。)

/********************************//*Problem:POJ 2299    *//*User:     shinelin    *//*Memory:     7228K    *//*Time:     438MS    *//*Language: C++        *//********************************/#include <cstdio>#include <iostream>#include <cstdlib>#include <ctime>#include <cctype>#include <cstring>#include <string>#include <list>#include <map>#include <queue>#include <deque>#include <stack>#include <vector>#include <set>#include <algorithm>#include <cmath>using namespace std;#define INF 0x7fffffff#define LL long long#define MAXN 500005LL a[MAXN], com[MAXN];LL cnt = 0;void swapTimes(int low, int high){    if(low == high - 1)        return ;    if(low == high - 2)    {        if(a[low] > a[low + 1])        {            swap(a[low], a[low + 1]);            cnt ++;        }        return ;    }    int mid = (low + high) >> 1;    swapTimes(low, mid);    swapTimes(mid, high);    int i = low, j = mid;    int k = low;    //三个游标    while (k < high)    {        if(j == high|| i < mid && a[i] <= a[j])        {            com[k++] = a[i++];        }        if(k == high) break;        if(i == mid || j < high && a[i] > a[j])        {            com[k++] = a[j++];            cnt += mid - i;     //归并排序的过程中,统计交换次数。        }    }    for (int i = low; i < high; i ++)    {        a[i] = com[i];    }    return ;}int main(){    int n;    while(~scanf("%d", &n), n)    {        cnt = 0;        for (int i = 0; i < n; i ++)        {            scanf("%I64d", a + i);        }        swapTimes(0, n);        printf("%I64d\n", cnt);//        for (int i = 0; i < n; i ++)//        {//            printf("%d ", a[i]);//        }//        printf("\n");    }    return 0;}



0 0