POJ_2299_Ultra-QuickSort

来源:互联网 发布:sql 2005 64位个人版 编辑:程序博客网 时间:2024/06/07 01:40

Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536KTotal Submissions: 48763 Accepted: 17823

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

这题目匪夷所思的配图

简单的线段树问题

问交换排序的最小次数

这个题目显然不能用模拟的方法来解决

那么其实交换次数就是目前串的逆序数(每次交换可以至多减少一个逆序数)

因此也就变成了求一个数字出现前有多少个数比他小(或者说有多少个数比他大)

那么这个操作用线段树就很容易实现了

问题在于这个问题中的数据范围,并不能开一个足够大的数组,考虑到这一点所以,需要把输入的数据进行转化

我用的办法就是用一个结构体记录输进来数字的大小和位置

按照大小排序,然后把大小转化成一个比较小的范围(因为输入的个数比较小)

然后再按位置排序,之后进行树状数组的操作来求个数

代码如下

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int M=5e5+5;int tree[M];struct NODE{    int v,p;      //值与位置}node[M];bool cmp1(NODE a,NODE b)//按位置排序{    return a.p<b.p;}bool cmp2(NODE a,NODE b)//按值排序{    return a.v<b.v;}inline int lowbit(int x){    return x&(-x);}void add(int x,int v){    for(int i=x;i<M;i+=lowbit(i))        tree[i]+=v;}int getsum(int x){    int s=0;    for(int i=x;i;i-=lowbit(i))        s+=tree[i];    return s;}int main(){    int n;    int num;    long long tot;    while(1)    {        scanf("%d",&n);        if(!n)            break;        tot=0;        memset(tree,0,sizeof(tree));        for(int i=0;i<n;i++)        {            scanf("%d",&num);            node[i].v=num;            node[i].p=i;        }        sort(node,node+n,cmp2);        for(int i=0;i<n;i++)            node[i].v=i;        sort(node,node+n,cmp1);        for(int i=0;i<n;i++)        {            tot+=i-getsum(node[i].v);            add(node[i].v+1,1);        }        printf("%I64d\n",tot);    }    return 0;}



0 0
原创粉丝点击