这个题首先按v排序不难想到,然后剩下的就是要快速求出在这之前的牛和现在牛的距离绝对值之和,我的想法是用2个树状数组进行维护,一个记录和,一个记录了有多少个,那么我们就可以快速算出距离和,从而可以快速解决问题
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=2e4+100;
struct Cow
{
int pos;
int v;
bool operator < (const Cow &a)const
{
return v<a.v;
}
}a[maxn];
int n;
int t[maxn],num[maxn];
int lowbit(int x)
{
return x&(-x);
}
void Update(int *t,int x,int val)
{
for(;x<maxn;t[x]+=val,x+=lowbit(x));
}
int Sum(int *t,int x)
{
int ans=0;
for(;x>0;ans+=t[x],x-=lowbit(x));
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(t,0,sizeof(t));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].v,&a[i].pos);
sort(a,a+n);
long long sum=0,ans=0;
for(int i=0;i<n;i++)
{
int val=Sum(t,a[i].pos);
int snum=Sum(num,a[i].pos);
ans+=a[i].v*(a[i].pos*snum-val+sum-val-a[i].pos*(i-snum));
sum+=a[i].pos;
Update(t,a[i].pos,a[i].pos);
Update(num,a[i].pos,1);
}
printf("%I64d\n",ans);
}
return 0;
}