POJ 2299 Ultra-QuickSort (树状数组 或 归并排序)

Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 30129   Accepted: 10760

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

Source

 
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=500005;

int n,c[maxn];
int b[maxn];

int lowbit(int x){
    return x&(-x);
}

int Sum(int p){
    int sum=0;
    while(p>0){
        sum+=c[p];
        p-=lowbit(p);
    }
    return sum;
}

void Update(int p,int val){
    while(p<=n){
        c[p]+=val;
        p+=lowbit(p);
    }
}

struct node{
    int num,id;
}a[maxn];

int cmp(node a,node b){
    return a.num<b.num;
}

int main(){
    while(scanf("%d",&n) && n){
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        int i;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i].num);
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        b[a[1].id]=1;
        for(i=2;i<=n;i++)
            if(a[i].id!=a[i-1].id)
                b[a[i].id]=i;
            else
                b[a[i].id]=b[a[i-1].id];
        long long ans=0;
        for(i=1;i<=n;i++){
            Update(b[i],1);
            ans+=Sum(n)-Sum(b[i]);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

归并排序:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N=500010;
const int INF=0x3f3f3f3f;

int n;
long long ans;

void Cal(int num[],int low,int mid,int high){
    int len_L=mid-low+1;
    int len_R=high-mid;
    int* left=new int[len_L+2];
    int* right=new int[len_R+2];
    int i,j;
    for(i=1;i<=len_L;i++)
        left[i]=num[low+i-1];
    left[len_L+1]=INF;
    for(j=1;j<=len_R;j++)
        right[j]=num[mid+j];
    right[len_R+1]=INF;

    i=j=1;
    for(int k=low;k<=high;){
        if(left[i]<=right[j])
            num[k++]=left[i++];
        else{
            num[k++]=right[j++];
            ans+=len_L-i+1;
        }
    }
    delete left;
    delete right;
}

void Mergesort(int num[],int low,int high){
    int mid;
    if(low<high){
        mid=(low+high)>>1;
        Mergesort(num,low,mid);
        Mergesort(num,mid+1,high);
        Cal(num,low,mid,high);
    }
}

int main(){

    //freopen("input.txt","r",stdin);

    int num[N];
    while(~scanf("%d",&n) && n){
        for(int i=1;i<=n;i++)
            scanf("%d",&num[i]);
        ans=0;
        Mergesort(num,1,n);
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2013-01-03 22:20  Jack Ge  阅读(202)  评论(0编辑  收藏  举报