POJ 2299 Ultra-QuickSort

题目链接:http://poj.org/problem?id=2299

用了树状数组,求逆序数。读入这些数,每读一个数就update一次,看一下它前面比它小的已出现过的有多少个sum(),然后用当前的位置-当前的sum(),就可以得到当前逆序对数了,加起来就得到总的逆序对数。

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;



#define N 500010



int n,c[N],reflect[N];

struct Node

{

    int val;

    int pos;

} node[N];



bool cmp(Node a,Node b)

{

    return a.val<b.val;

}



int lowbit(int x)

{

    return x & (-x);

}



void update(int i)

{

    while(i<=n)

    {

        c[i]+=1;

        i+=lowbit(i);

    }

}



int sum(int i)

{

    int s=0;

    while(i>0)

    {

        s+=c[i];

        i-=lowbit(i);

    }

    return s;

}



int main()

{

    int i,j;

    while(scanf("%d",&n),n)

    {

        for(i=1; i<=n; i++)

        {

            scanf("%d",&node[i].val);

            node[i].pos=i;

        }

        sort(node+1,node+n+1,cmp);

        for(i=1; i<=n; i++)

        {

            c[i]=0;

            reflect[node[i].pos]=i;

        }

        long long int ans=0;

        for(i=1; i<=n; i++)

        {

            update(reflect[i]);

            ans += i-sum(reflect[i]);

        }

        printf("%lld\n",ans);

    }

    return 0;

}

 

你可能感兴趣的:(Quicksort)