美文网首页
POJ 2299 Ultra-QuickSort 归并排序求逆序

POJ 2299 Ultra-QuickSort 归并排序求逆序

作者: Vchar_Fred | 来源:发表于2018-04-13 18:56 被阅读0次

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

题目大意,给你一串每个元素不相同的序列,每次只能相邻的两个元素进行交换,求,最小多少次交换可以使该序列成为上升序列。

注意:明白一个规律,一个数x,肯定要和在它左边且比它大的数进行交换,即求逆序数。

struct node{
    int elem;
    int old;
};
node arr[500010];
int a[500010];
int c[500010];
int n;
int cmp(node a, node b)
{
    return a.elem <= b.elem;
}
int main()
{
    int i;
    while(scanf("%d", &n) && n)
    {
        memset(c, 0, sizeof(c));
        arr[0].elem = -1;
        arr[0].old = 0;
        for(i = 1; i <= n; i )
        {
            scanf("%d", &arr[i].elem);
            arr[i].old = i;
        }
        sort(arr, arr n 1, cmp);//排序
        for(i = 1; i <= n; i )//将新排好序的下标一一对应存下来;
        {
            a[arr[i].old] = i;
        }
        double sum_ = 0;
        for(i = 1; i <= n; i )
        {
            add(a[i], 1);//将这个数插入
            sum_ = i - sum(a[i]);//得到比当前这个数大,并且初始时在它的左边的数的个数;即得到它的最优移动次数。
        }
        printf("%.0lf\n", sum_);
    }
    return 0;
}
int lowbit(int x)
{
    return x&(-x);
}
double sum(int end_)
{
    double sum = 0;
    while(end_ > 0)
    {
        sum = c[end_];
        end_ -= lowbit(end_);
    }
    return sum;
}
void add(int i, int elem)
{
    while(i <= n)
    {
        c[i] = elem;
        i = lowbit(i);
    }
    return ;
}

相关文章

  • Chapter6——基础算法——排序

    1. 题目列表 POJ2388(排序,水题) POJ2299(求逆序对,归并排序、树状数组、线段树) 2. PO...

  • POJ 2299 Ultra-QuickSort 归并排序求逆序

    Description In this problem, you have to analyze a partic...

  • POJ 1804

    POJ 1804 题意 求逆序数 思路 在网上看到可以用归并排序,由于数据较小,可以直接求。

  • POJ 2299 Ultra-QuickSort

    这是个解决分治问题的好题目,来看看 题目:给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该...

  • 排序算法

    常考排序 快速排序 归并排序 归并排序求逆序数对 堆排序 堆排序是指利用堆这种数据结构所设计的一种排序算法。 堆积...

  • Ultra-QuickSort POJ - 2299 (树状数组

    题目来源:Ultra-QuickSort 题意 现在随机给你一组数,每次可以交换相邻的两个数,问最少交换几次可以使...

  • ologn排序算法后的两个问题

    求一个数组的逆序数对的个数(归并排序) 求出nums里第k小的数(快速排序)

  • 二分(三分)

    题目链接:二分·归并排序之逆序对 题目链接:三分·三分求极值

  • 归并排序求逆序对

    归并排序 归并排序是我们最常使用的排序算法之一,作用是将两个或两个以上的有序数组合并成为一个新的数组,主要使用的是...

  • 2018-03-16

    碰到的算法并查集逆序对归并排序分治算法

网友评论

      本文标题:POJ 2299 Ultra-QuickSort 归并排序求逆序

      本文链接:https://www.haomeiwen.com/subject/gyaqkftx.html