QAQ
用声音进行升序排序,用树状数组记录比当前值(x)小的有几个,以及那些数的前缀和
ans+=(cnt(比其小的数的个数)* 当前值-前缀和)* voice
至于当前值大的值可以用当前的总和-前缀和,至于大的数的个数同理
再加上后面的数的贡献就行了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
struct tw{
long long fal;
long long voe;
}a[99999];
long long maxn=-1;
long long sum[99999],tot[999999];
long long cnt,ps;
void add(long long x,long long w1,long long w2)
{
for(long long i=x;i<=maxn;i+=i&-i)
sum[i]+=w1,tot[i]+=w2;
}
void ask(int x)
{
for(long long i=x;i>0;i-=i&-i)
cnt+=sum[i],ps+=tot[i];
}
bool comp(const tw&a,const tw&b)
{
return a.voe<b.voe;
}
int main()
{
int n;
long long ans=0;
scanf("%d",&n);
long long zh=0;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i].voe,&a[i].fal);
maxn=max(a[i].fal,maxn);
}
sort(a+1,a+n+1,comp);
for(int i=1;i<=n;i++)
{
zh+=a[i].fal;
ps=0;
cnt=0;
add(a[i].fal,1,a[i].fal);
ask(a[i].fal);
ans+=(cnt*a[i].fal-ps)*a[i].voe;
cnt=i-cnt;
ps=zh-ps;
ans+=(ps-cnt*a[i].fal)*a[i].voe;
}
printf("%lld",ans);
return 0;
}