原題連結
題解
\(O(n^2)\) 不可能,所以考慮線性,將奶牛按下標排序,順序遍歷,對於 \(i\) 而言,它的貢獻等於 \(\sum_{j\lt i\ ,\ v[j]\leqslant v[i]}{dis(i,j)·v[i]}\) ,等於 \(v[i]·((\sum_{j\lt i\ ,\ v[j]\leqslant v[i]}{1})·x[i]-\sum_{j\lt i\ ,\ v[j]\leqslant v[i]}{x[j]})\)
逆序遍歷貢獻為 \(v[i]·((\sum_{j\gt i\ ,\ v[j]\lt v[i]}{1})·x[i]-\sum_{j\gt i\ ,\ v[j]\lt v[i]}{x[j]})\)
把 \(v\) 看作x軸 , 等價於求 小於v的個數 和 小於v的dis和 ,用兩個樹狀陣列解決
code
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
#define ll long long
inline void read(ll &x) {
x = 0;
ll flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
x *= flag;
}
inline void write(ll x)
{
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
ll n;
struct node
{
ll v,x,haxi;
} cow[50005];
ll cnt[50005]={0}, sum[50005]={0};
ll query_cnt(ll x)
{
ll cal=0;
while(x)
{
cal+=cnt[x];
x-=lowbit(x);
}
return cal;
}
ll query_sum(ll x)
{
ll cal=0;
while(x)
{
cal+=sum[x];
x-=lowbit(x);
}
return cal;
}
void update_cnt(ll x)
{
while(x<=50005)//Because x is small, discretization is not necessary.
{
cnt[x]++;
x+=lowbit(x);
}
}
void update_sum(ll x, ll val)
{
while(x<=50005)
{
sum[x]+=val;
x+=lowbit(x);
}
}
bool cmp(node a, node b)
{
return a.x<b.x;
}
int main()
{
ll n;
read(n);
for(ll i=1; i<=n; i++)
{
read(cow[i].v);
read(cow[i].x);
}
ll ans=0;
sort(cow+1, cow+1+n, cmp);
for(ll i=1; i<=n; i++)
{
ll index=cow[i].v;
ans+=cow[i].v*(query_cnt(index)*cow[i].x-query_sum(index));
update_cnt(index);
update_sum(index, cow[i].x);
}
memset(cnt, 0, sizeof cnt);
memset(sum, 0, sizeof sum);
for(ll i=n; i>=1; i--)
{
ll index=cow[i].v;
ans+=cow[i].v*(query_sum(index-1)-query_cnt(index-1)*cow[i].x);
update_cnt(index);
update_sum(index, cow[i].x);
}
write(ans);
return 0;
}