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;

}

 

你可能感兴趣的:(sort)