Cow Sorting

hdoj 2838

题目大意:给出数,求排成正序的最少时间,每两个数交换的时间是 两个数的值的和。

解决:树状数组,只需求出 在这个数加入之前比这个数大的个数,然后更新,再求出这个数加入之前比这个数大的数的总和

总共的代价是:cnt*加入的数+比这个数大的数的和

#include <iostream>

#include <functional>

#include <algorithm>

using namespace std;

#define LL __int64

const int N=100000;

LL sum[N+5]; //第i个数前比数num[i]大的数的和 

LL cnt[N+5]; //第i个数前比数num[i]大的数的个数

inline int lowbit(int x)

{

    return x&(-x);

}



void update(LL t[],int p,int delta)

{

    for(int i=p;i>0;i-=lowbit(i))

       t[i]+=delta;

}

LL getsum(LL t[],int p)

{

    LL tot=0;

    for(int i=p;i<=N;i+=lowbit(i))

      tot+=t[i];

    return tot;  

}



int main()

{

       int n, t;

        scanf("%d",&n);

   

        LL ans=0;

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

        {

            scanf("%d",&t);

           //注意这个tmp必须是LL长整型的

            LL tmp=getsum(cnt,t+1);

            update(cnt,t,1);

            //这个s必须是长整型的,就是这个地方错了好几次的。

            LL s=getsum(sum,t+1);

            update(sum,t,t);

            ans += tmp*t+s;

        }

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



    system("pause");

    return 0;

} 

 

 

你可能感兴趣的:(sort)