POJ 2299:Ultra-QuickSort

Ultra-QuickSort

Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 39397   Accepted: 14204

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

归并排序。

另外,此题有一坑就是结果会超int32;

详细能够參考:点击打开链接

我写的代码例如以下:

#include<cstdio>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;

const int M = 500000 + 5;
int n, A[M], T[M], i;

long long merge_sort(int l, int r, int *A)
{
    if (r - l < 1) return 0;
    int mid = (l + r) / 2;
    long long ans = merge_sort(l, mid, A) + merge_sort(mid + 1, r, A);
    i = l;
    int p = l, q = mid + 1;
    while (p <= mid && q <= r)
    {
        if(A[p] <= A[q])
            T[i++] = A[p++];
        else
        {
            ans += (mid + 1 - p);
            T[i++] = A[q++];
        }
    }
    while (p <= mid) T[i++] = A[p++];
    while (q <= r) T[i++] = A[q++];
    for (int j = l; j <= r; j++)
        A[j] = T[j];
    return ans;
}

int main()
{
    int n;
    while(scanf("%d", &n) && n)
    {
        for(int j=0; j<n; j++)
            scanf("%d", &A[j]);
       printf("%lld\n", merge_sort(0, n - 1, A));
    }

    return 0;
}
时间: 2024-10-27 04:35:34

POJ 2299:Ultra-QuickSort的相关文章

树状数组求逆序对:POJ 2299、3067

前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换相邻的两数使它有序,要你求出交换的次数.实质上就是求逆序对,网上有很多人说它的原理是冒泡排序,可以用归并排序来求出,但我一时间想不出它是如何和归并排序搭上边的(当初排序没学好啊~),只好用刚学过的树状数组来解决了.在POJ 1990中学到了如何在实际中应用上树状数组,没错,就是用个特殊的数组来记录即

POJ 2299 Ultra-QuickSort(归并排序求逆序对数)

题目地址:POJ 2299 今天下午的多校看来没有白做...实在做不出题闲着无聊看小白鼠学会了个归并排序.哈哈. 归并排序简单地说其实就是先分成一个二叉树直至单个,然后依次从最底层不断进行合并,逆序对数就是在合并的过程中,加入后面的那段中到了比他大的时候,那后面的那些就都是比他大的,都是逆序对数,所以直接加上即可.网上资料很多,就不细说了..用了分治的思想. 自己根据理解写的代码,考虑的太不全面了..又调了好长时间... 代码如下: #include <algorithm> #include

poj 2299 Ultra-QuickSort (树状数组+离散化)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 48257   Accepted: 17610 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

POJ 2299 Ultra-QuickSort (求序列的逆序对数)

题意:废话了一大堆就是要你去求一个序列冒泡排序所需的交换的次数. 思路:实际上是要你去求一个序列的逆序队数 看案例: 9 1 0 5 4 9后面比它小的的数有4个 1后面有1个 0后面没有 5后面1个 4后面没有 所以结果为4+1+0+1+0=6 所以逆序对的定义如果不清楚可以自己总结了 这道题说白了就是要你用归并排序求逆序对数. 下面是搜到某牛给的逆序对数的方法: 假设回溯到某一步,后面的两部分已经排好序(就是说当前需要归并的两个部分都是分别有序的),假设这两个序列为 序列a1:2 3 5 9

poj 2299 Ultra-QuickSort (归并排序,逆序数)

链接:poj 2299 题意:给出长度为n的序列,每次只能交换相邻的两个元素, 问至少要交换几次才使得该序列为递增序列 分析:冒泡排序每次只能交换相邻两个元素,也就是求 用冒泡排序使其为递增序列的交换次数,每交换一次记录一次就好 但是这题数据较大,冒泡排序效率比较低,会超时的 这里就可以利用归并排序了,用归并排序可以求序列的逆序数, 而一个序列的 逆序数 = 只允许相邻两个元素交换时,得到有序序列的交换次数 #include<stdio.h> #include<stdlib.h>

Poj 2299 Ultra-QuickSort 树状数组 解法

本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单. 就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果. 例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的. 9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗? 对,就是这么简单的方法, 就叫做离散化. 如果你对counting sort熟悉的话,那么这样的思想理解

POJ 2299 逆序对(归并排序)

终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系列的问题所困扰,然后又只能自己一个人摸索,也是一段辛酸忧伤史,现在小结一下上个月在做二维码的过程中所碰到的问题以及解决办法,现在庆幸终于解决好了,终于能将这个功能告一段落,一下小结也是分享一下Unity的某些"坑",让同行少走弯路,起码在二维码这方面应该会有所启迪,欣慰的是接下来几天终于可以做自己应该做的事情了! 效果图: 先小结一下碰到的问题: 1.Unity工程屏幕方向与Android工程屏幕方向要一致的问题 本来

POJ 2299 Ultra-QuickSort (离散化+树状数组)

题目链接:POJ 2299 Ultra-QuickSort 求一串序列相邻连个元素交换多少后,是一串上升的序列. 思路:求该串序列的逆序数,数据比较大,要离散化. AC代码: #include<stdio.h> #include<string.h> #include<set> #include<map> #include<algorithm> #define ll __int64 using namespace std; const ll max

POJ 2299 Ultra-QuickSort(线段树+离散化)

题目地址:POJ 2299 这题曾经用归并排序做过,线段树加上离散化也可以做.一般线段树的话会超时. 这题的数字最大到10^10次方,显然太大,但是可以利用下标,下标总共只有50w.可以从数字大的开始向树上加点,然后统计下标比它小即在它左边的数的个数.因为每加一个数的时候,比该数大的数已经加完了,这时候坐标在它左边的就是一对逆序数. 但是该题还有一个问题,就是数字重复的问题.这时候可以在排序的时候让下标大的在前面,这样就可以保证加点的时候下标比他小的数中不会出现重复的. 这题需要注意的是要用__