poj2299 Ultra-QuickSort 树状数组

来源:互联网 发布:少女时代减肥 知乎 编辑:程序博客网 时间:2024/05/16 13:57

Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536KTotal Submissions: 54997 Accepted: 20235

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

Source

Waterloo local 2005.02.05

作为树状数组的入门级题目。。。。关于树状数组的二进制部分还是看得一知半解,但大概明白其用法

该题要求我们用冒泡排序来处理题目给我们的一个序列,算出一共要交换多少次数字才能排序完成

想一想就可发现,每个数字要交换多少次取决于它左边比它大的数字有多少个。

直接暴力统计的话会超时,所以使用树状数组

先将输入的数据离散化(题中保证每个数字只出现一次)

然后将树状数组清零,接着用离散化的数据对树状数组相应的位置进行标记(0——>1)。

那么getsum[after[x]]就可以得到在离散化处理后的after[x]这个位置上,比它小的数有多少个,那么用当前的位置减去比它小的数就是比它大的数了

下面是代码:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <map>#include <set>#include <vector>using namespace std;const int maxn=500005;int n,c[maxn],after[maxn];struct unit{    long long num;    int position;};unit save[maxn];int lowbit(int x){    return x&(-x);}void update(int x,int val){    while(x<=maxn){        c[x] += val;        x += lowbit(x);    }}int getsum(int x){    int sum=0;    while(x>0){        sum += c[x];        x -=lowbit(x);    }    return sum;}bool compare(unit a,unit b){    return a.num<b.num;}int main(){    int i;    while(~scanf("%d",&n)&&n){        for(i=1;i<=n;i++){            scanf("%lld",&save[i].num);            save[i].position=i;        }        sort(save+1, save+1+n, compare);        for(i=1;i<=n;i++){            after[save[i].position]=i;        }        memset(c, 0, sizeof(c));        long long ans=0;        for(i=1;i<=n;i++){            update(after[i], 1);            ans += i-getsum(after[i]);        }        printf("%lld\n",ans);            }        return 0;}


0 0