HDU_2689_Sort it

其实,这道题暴力也行,两个for就搞定了,时间复杂度为O(N^2),而树状数组的时间复杂度为O(N*logN)。

树状数组求逆序对的原理:

前面有i-1个数,把每次输入的数看作树状数组的下标,设置增加的变量为1,算其前缀和(有多少个1就有多少个顺序对),然后减去顺序对就是答案,方案有两种(本质是一样的):

1、

ans+=(i-1-sum(a));

add(a);

2、

add(a);
ans+=(i-sum(a));

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
#define N 1005
int c[N];
int sum(int x)
{
    int ret=0;
    while(x)
    {
        ret+=c[x];
        x-=(x&-x);
    }
    return ret;
}
void add(int x)
{
    while(x<=N)
    {
        c[x]++;
        x+=(x&-x);
    }
}
int main()
{
    int t,a,ans;
    while(~scanf("%d",&t))
    {
        memset(c,0,sizeof(c));
        ans=0;
        for(int i=1;i<=t;++i)
        {
            scanf("%d",&a);
            add(a); 
            ans+=(i-sum(a));
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-05-23 09:56  小仪在努力~  阅读(149)  评论(0编辑  收藏  举报