Cow Sorting HDU - 2838

题意:就是求将之前的排列变成一个递增的排列,每交换两个数的代价为两个数的和,求变成递增的排列所需的最小代价为多少。

本题相当于冒泡排序,对于冒泡排序,每个点的贡献价值的次数等于前面大于它的数的个数加上后面小于它的个数。

分析:其实这个结果和逆序数有关,对某个位置i,如果前面比他大的有x个,那么a[i]至少要加x次 
如果后面有y个比a[i]小,那么a[i]至少要加y次,也就是说用两个树状数组来分别维护当前位置时前面有多少比他大,后面有多少个比他小

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int n=101000;
long long C[101000];
int M[101000];
long long lowbit(int i)
{
    return i&-i;
}
void update(int i,int val)
{
    while(i<=n)
    {
        C[i]=C[i]+val;
        i=i+lowbit(i);
    }
}
long long sum(int i)
{
    long long ret=0;
    while(i>0)
    {
        ret=ret+C[i];
        i=i-lowbit(i);
    }
    return ret;
}
void init()
{
    memset(C,0,sizeof(C));
    memset(M,0,sizeof(M));
}
int main()
{
    int k;
    while(scanf("%d",&k)!=EOF)
    {
        init();
        long long ans=0;
        for(int i=0;i=0;i--)
        {
            ans=ans+(sum(M[i]-1))*M[i];
            update(M[i],1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

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