poj 2299 Ultra-QuickSort

来源:互联网 发布:淘宝运动品牌店铺排名 编辑:程序博客网 时间:2024/06/12 18:53

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

6

0

题意:就是说冒泡排序的时候的交换次数是多少。

思路:用树状数组,先把数据离散化一下,节省内存,为什么要用离散化呢,如果告诉你数据范围是10^9,数据量是10^4没法开那么大的数组,离散化之后,只需要开10^4

大小的数组就行了,然后按照初始位置放到树状数组里,进行计算就行了,因为不是区间求和,树状数组C标记为1,即代表此数已经放进树状数组里了。放进数组里之后判断

比其小的数是否已经在里面了,确定排序时移动的次数(实在不明白的话,先搞懂树状数组,然后手动模拟代码)。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int n;int c[500005];int reflect[500005];struct node {    int p;    int num;} a[500005];int cmp(node x,node y) {    return x.num < y.num;}int lowbit(int x) {    return x&(-x);}void build(int p,int num) {    while(p<=n) {        c[p]+=num;        p+=lowbit(p);    }}int sum(int x) {    int ans=0;    while(x>0) {        ans+=c[x];        x-=lowbit(x);    }    return ans;}int main() {    int i;    while(scanf("%d",&n)!=EOF && n) {        for(i=1; i<=n; i++) {            scanf("%d",&a[i].num);            a[i].p=i;//记录这个数据的初始位置        }        sort(a+1,a+1+n,cmp);//排序的目的就是为了方便进行离散化        memset(c,0,sizeof(c));        for(i=1; i<=n; i++) {            reflect[a[i].p]=i;//离散化,为了节省空间(因为开树状数组是根据数的大小开的数组)        }        long long ans=0;        for(i=1; i<=n; i++) {            build(reflect[i],1);            ans+=i-sum(reflect[i]);//判断放进去以后  比其小的数有没有被放进来,从而得到要换多少次        }         printf("%lld\n",ans);    }}



0 0