hdu 1394 树状数组

思路:从后面往前面统计,每次先sum+=Sum(num[i]+1),然后在update(num[i]+1,1)。这样每次Sum每次加的个数就是num[i]的逆序对个数。

每次从队首调一个元素到队尾,逆序对的变化为sum=sum-num[i]+n-num[i]+1。减少的个数为num[i],增加的个数为n-num[i]-1。

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#define Maxn 5010

#define lowbit(x) (x&(-x))

using namespace std;

int C[Maxn],num[Maxn],n;

void init()

{

    memset(C,0,sizeof(C));

}

int Sum(int pos)

{

    int sum=0;

    while(pos>0)

    {

        sum+=C[pos];

        pos-=lowbit(pos);

    }

    return sum;

}

void update(int pos)

{

    while(pos<=n)

    {

        C[pos]++;

        pos+=lowbit(pos);

    }

}

int main()

{

    int i,j;

    while(scanf("%d",&n)!=EOF)

    {

        init();

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

             scanf("%d",num+i);

        int sum=0,ans;

        for(i=n;i>=1;i--)

        {

            sum+=Sum(num[i]+1);

            update(num[i]+1);

        }

        ans=sum;

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

        {

            sum=sum-num[i]+n-num[i]-1;

            if(sum<ans)

                ans=sum;

        }

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

    }

    return 0;

}

 

你可能感兴趣的:(树状数组)