P5094 [USACO04OPEN] MooFest G 加強版

纯粹的發表於2024-04-15

原題連結

題解

\(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;
}

相關文章