题意:给出牛的耳聋程度和牛所在的位置,之后求出每两个牛所能听到对方的声音的和,每两个牛的计算公式为max(vi,vj)*|xi-xj|
题解:首先暴力肯定是不行的,那么可以按照牛的音量进行从小到大排序,然后维护两个树状数组,一个维护此位置之前之后的牛的个数,另一个维护此位置之前之后的牛的位置之和,之后求和即可.
附上代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e4+50;
pair<int,int>cow[maxn];
int n;
ll cnt[maxn],dis[maxn];
int lowbit(int i)
{
return i&(-i);
}
ll sum(ll *bit,int i)
{
ll res=0;
while(i>0){
res+=bit[i];
i-=lowbit(i);
}
return res;
}
ll sum(ll *bit,int from,int to)
{
return sum(bit,to)-sum(bit,from);
}
void add(ll *bit,int i,ll x)
{
while(i<=maxn){
bit[i]+=x;
i+=lowbit(i);
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&cow[i].first,&cow[i].second);
}
sort(cow,cow+n);
ll ans=0;
for(int i=0;i<n;i++){
int v=cow[i].first,x=cow[i].second;
int lcnt=sum(cnt,0,x),rcnt=sum(cnt,x,maxn);
ans+=v*((x*lcnt-sum(dis,0,x))+(sum(dis,x,maxn)-rcnt*x));
add(cnt,x,1);
add(dis,x,x);
}
printf("%lld\n",ans);
return 0;
}