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

POJ2299 原题链接:http://poj.org/problem?id=2299

Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 63588   Accepted: 23705

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


原题大意:输入一串数据,求它的逆序数;

思路:暴力的方法肯定超时,用树状数组可以将复杂度降到O(nlogn);

这道题大体的思路为:

1.开一个能大小为这些数的最大值的树状数组,并全部置0;

2.从头到尾读入这些数,每读入一个数就更新树状数组,查看它前面比它小的已出现过的有多少个数sum;

3.用当前位置减去该sum,就可以得到当前数导致的逆序对数了。把所有的加起来就是总的逆序对数;


但是,题目给的一个数的范围最大为999,999,999显然我们的树状数组不能开到那么大;这里要用到离散化,就是把输入的所有数离散化到1~n的范围内在进行1~3步的操作;


离散化过程:

1.创建一个结构体

const int N=5e5+10;
typedef struct{
    int val;   //输入值
    int pos;   //原下标
}NODE;
NODE node[N];
在创建一个数组a[N];

把node[N]按照val的值从小到大排列之后令 a[node[i].pos]=i (i=1,2,3,4,5,6...n)

过程如下:

1.拿题目第一个样例,输入的为 val: 9 1 0 5 4;

                             其原下标为pos: 1 2 3 4 5;

                                   node[i]的   i: 1 2 3 4 5;

2.排序之后  val: 0 1 4 5 9                             

                  pos: 3 9 5 4 1                            

                           i: 1 2 3 4 5                                

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值