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; }