题目大意:n只奶牛,第i只听力为vi,坐标为xi,两只奶牛聊天时音量是max(vi,vj)∗abs(xi−xj)。求n(n−1)/2对奶牛的音量和
题解:经验告诉我们,有比较的题就先排序……
按照x轴从大到小排序,这样用树状数组维护坐标就行了
对于绝对值,可以拆成正负分别计算,因此还需要维护一个区间数量
我的收获:排序大法吼,比较先排序
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=20000;
int n,num[N+5],cnt;
long long sum[N+5],ans,tot;
struct abc{int v,x;}a[N+5];
bool cmp(abc x,abc y){return x.v>y.v;}
void add(int x,int v,int k)
{
for(int i=x;i<=N;i+=i&(-i))
sum[i]+=v,num[i]+=k;
}
void query(int x)
{
for(int i=x;i>0;i-=i&(-i))
tot+=sum[i],cnt+=num[i];
}
void work()
{
for(int i=1;i<=n;i++){
tot=cnt=0;
query(a[i].x);
ans+=a[i].v*(cnt*a[i].x-tot);
cnt=-cnt,tot=-tot;
query(N);//全部-比x小的部分
ans+=a[i].v*(tot-cnt*a[i].x);
add(a[i].x,-a[i].x,-1);//删掉x
}
cout<<ans<<endl;
}
void init()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].v,&a[i].x);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++) add(a[i].x,a[i].x,1);
}
int main()
{
init();
work();
return 0;
}