1 条题解

  • 0
    @ 2025-8-24 23:17:44

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Ghosty_Neutrino
    ♬ Just do it!♬

    搬运于2025-08-24 23:17:44,当前版本为作者最后更新于2025-06-08 22:12:16,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意

    数轴上有 NN 个村庄,每个村庄位于位置 xix_i,有 aia_i 个居民。对于每个查询位置 qiq_i,计算所有居民到 qjq_j 的累计距离 f(qj)=i=1Nai×xiqjf(q_j) = \sum_{i=1}^N a_i \times |x_i - q_j|

    分析

    根据绝对值的性质,可以得到两种情况:

    • xiqx_i \leq q 时,xiq=qxi|x_i - q| = q - x_i
    • xi>qx_i > q 时,xiq=xiq|x_i - q| = x_i - q

    累计距离可拆分为两部分计算:

    $$f(q) = \sum_{x_i \leq q} a_i (q - x_i) + \sum_{x_i > q} a_i (x_i - q) $$

    预处理这两部分的前缀和,就能快速计算累计距离,所以接下来我们就来预处理一下这两个部分。

    首先将村庄按位置 xix_i 升序排序。排序后,所有村庄的位置形成有序序列,便于后续二分查找分割点。

    定义数组 sumasumasumaksuma_k 表示前 kk 个村庄的居民总数。再定义数组数组 sumxasumxasumxaksumxa_k 表示前 kk 个村庄的 aixia_i x_i 总和。

    接下来用二分查找分割点,使用二分查找找到第一个满足 xiqx_i \geq q 的村庄下标 kk。此时前 kk 个村庄的位置均 <q< q,如果 xk=qx_k = q,则包含在左边或右边都行。从 kkN1N-1 的村庄位置均 q\geq q

    于是我们可以累计距离啦,分左右分别计算,左边有 kk 个村庄,右边有 NkN-k 个村庄。最后把左右两边的距离加起来就行了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n,q,k;
    ll o,l,r;
    struct D{
        ll x,a;
        bool operator<(const D&w)const{return x<w.x;}
    };
    int main() {
        ios::sync_with_stdio(false);//快读快写启动,我怕炸TLE
        cin.tie(nullptr); 
        cin>>n>>q;
        vector<D> v(n);
        for(int i=0;i<n;i++) cin>>v[i].a>>v[i].x;
        sort(v.begin(),v.end());
        vector<ll> suma(n+1,0);//前i个村庄的a总和
        vector<ll> sumax(n+1,0);//前i个村庄的a*x总和
        for(int i=0;i<n;i++){
            suma[i+1]=suma[i]+v[i].a;
            sumax[i+1]=sumax[i]+v[i].a*v[i].x;
        }
        for (int i=0;i<q;i++){
            cin>>o;
            k=lower_bound(v.begin(),v.end(),D{o,0})-v.begin();//二分查找第一个x>=q的村庄下标
            l=o*suma[k]-sumax[k];//左边的距离
            r=(sumax[n]-sumax[k])-o*(suma[n]-suma[k]);//右边的距离
            cout<<l+r<<endl;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    12459
    时间
    3000ms
    内存
    1024MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者