#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAX=20005;
int n;
pair<int,int> cow[MAX];
ll num[MAX],dis[MAX];
ll sum(ll *bit,int i)
{
ll s=0;
while(i>0)
{
s+=bit[i];
i-=i&(-i);
}
return s;
}
ll sum(ll *bit,int from,int to)
{
return sum(bit,to-1)-sum(bit,from-1);
}
void add(ll *bit,int i,ll x)
{
while(i<=MAX)
{
bit[i]+=x;
i+=i&(-i);
}
}
int main()
{
while(cin>>n)
{
for(int i=0;i<n;i++)
cin>>cow[i].first>>cow[i].second;
sort(cow,cow+n);
ll res=0;
for(int i=0;i<n;i++)
{
int h=cow[i].first,x=cow[i].second;
ll left=sum(num,1,x),right=i-left;
res+=h*((left*x-sum(dis,1,x))+(sum(dis,x+1,MAX)-right*x));
add(num,x,1);
add(dis,x,x);
}
cout<<res<<endl;
}
return 0;
}
好久未做线段树之类的题了,感觉生疏了许多,参考了一下别人的代码。
首先这一题使用了两个BIT,一个用来求左右两边的cow的个数,另外一个是用来记录所有点到原点的距离之和。
此外,此题先通过听力好坏程度排序,这样每次新更新的牛都是耳背的,不用再比较两个cow的的听力值了。