POJ - Ultra-QuickSort

题目大意

给定N个数(没有相同的值),对N个数进行升序排序,每次只能交换相邻的两个数,问最少需要多少次交换才能够让N个数成为升序排列的

题解

就是逆序对问题,如果a[i]>a[j](i<j)则就是一个逆序对,此题可以用归并排序解决,也可以树状数组,不过我是当树状数组来练习的。此题数据有点大0 ≤ a[i] ≤ 999,999,999,所以需要把N个数进行离散化,因为我们对每个数的值并不感兴趣,只需要知道每个数的大小即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500005
using namespace std;
typedef struct
{
    long id;
    long t;
} NODE;
NODE a[MAXN];
long long c[MAXN];
long f[MAXN];
long n;
long lowbit(long x)
{
    return x&-x;
}
long sum(long x)
{
    long ret=0;
    while(x>0)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void add(long x,long d)
{
    while(x<=n)
    {
        c[x]+=d;
        x+=lowbit(x);
    }
}
bool cmp(NODE x,NODE y)
{
    return  x.t<y.t;
}
int main(void)
{
    long i;
    long long ans;
    while(scanf("%ld",&n)==1&&n)
    {
        for(i=1; i<=n; i++)
        {
            scanf("%ld",&a[i].t);
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        memset(c,0,sizeof(c));
        for(i=1; i<=n; i++)
            f[a[i].id]=i;
            ans=0;
        for(i=n; i>=1; i--)
        {
            add(f[i],1);
            ans+=sum(f[i]-1);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

posted on 2013-04-17 15:10  仗剑奔走天涯  阅读(191)  评论(0编辑  收藏  举报

导航