HDU_2838_Cow Sorting

题意:

交换任意两个相邻奶牛的坐标,使得它们的暴怒值升序排列,题目已经限制了,每头牛的暴力值是唯一的

首先,我们看到数据范围10W,暴力的话,O(N^2)必挂,然后我们想到了树状数组

思路:对某个下标k,先求逆序对ans,然后已知k和前面的逆序数要两两交换,所以对于本次的k,交换的总值为v+k*ans,v是前面超了的值之和

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
#define LL long long
#define M 100001
int n;
struct point
{
    int num;
    LL val;
}p[M];
void add(int x,int d)
{
    
    while(x<=n)
    {
        p[x].num++;
        p[x].val+=d;
        x+=x&-x;
    }
}
int sum_n(int x)//求逆序对
{
    int ret=0;
    while(x)
    {
        ret+=p[x].num;
        x-=x&-x;
    }
    return ret;
}
LL sum_v(int x)
{
    LL ret=0;
    while(x)
    {
        ret+=p[x].val;
        x-=x&-x;
    }
    return ret;
}
int main()
{
    int i,j,k;
    while(~scanf("%d",&n))
    {
        LL final=0,ans;
        for(i=1;i<=n;++i)
        {
            scanf("%d",&k);
            add(k,k);
            ans=i-sum_n(k);
            if(ans)
            {
                LL v=sum_v(n)-sum_v(k);
                final+=(v+k*ans);
            }
        }
        cout<<final<<endl;
    }
    return 0;
}

 

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