Short Question

传送门

题意:
计算i=1Nj=1Nmin(|pipj|,|qiqj|)


思路:
可以转换为i=1Nj=1N(|pipj|+|qiqj|)i=1=1Nj=1Nmax(|pipj|,|qiqj|)
首先, 求曼哈顿距离,令 tp = q, tq = q 先对tp, tq进行排序, 然后求tp, tq的前缀和,在对每一个p, q进行lower_bound找到位置,直接相减处理
其次,先介绍下切比雪夫距离,max(|x1x2|,|y1y2|), 和上述的式子一比较,发现一模一样,pi=x1,pj=x2,qi=y1,qj=y2, 切比雪夫距离可以转换成曼哈顿距离,max(|x1x2|,|y1y2|) = |(x1+y1)/2(x2+y2)/2|+|(x1y1)/2+(x2y2)/2|, 利用这个转换成曼哈顿就可以直接计算求值了

总结:
曼哈顿可以用前缀和和sort来处理,切比雪夫可以转成曼哈顿


点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);
#define endl '\n'
using namespace std;

typedef long long ll;
const ll MAXN = 1e6 + 10;
ll n;
ll p[MAXN], q[MAXN], tp[MAXN], tq[MAXN], sump[MAXN], sumq[MAXN], pqi[MAXN], pqj[MAXN], tpqi[MAXN], tpqj[MAXN], sumpqi[MAXN], sumpqj[MAXN];

int main()
{
    IOS; cin.tie(0), cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> p[i], tp[i] = p[i];
    for (int i = 1; i <= n; ++i)
        cin >> q[i], tq[i] = q[i];
    sort(tp + 1, tp + 1 + n);
    sort(tq + 1, tq + 1 + n);  
    for (int i = 1; i <= n; ++i)
        sump[i] = sump[i - 1] + tp[i], sumq[i] = sumq[i - 1] + tq[i];
    ll sum = 0; //总的曼哈顿距离
    for (int i = 1; i <= n; ++i)
    {
        int posp = lower_bound(tp + 1, tp + 1 + n, p[i]) - (tp);
        int posq = lower_bound(tq + 1, tq + 1 + n, q[i]) - (tq);
        //cout << "posp: " << posp << endl; 
        sum += abs(sump[posp] - (posp) * p[i]) + abs(sump[n] - sump[posp] - (n - posp) * p[i]);
        sum += abs(sumq[posq] - (posq) * q[i]) + abs(sumq[n] - sumq[posq] - (n - posq) * q[i]); 
    }      
    //cout << "sum: " << sum << endl;
    for (int i = 1; i <= n; ++i)
    {
        pqi[i] = (p[i] + q[i]);
        tpqi[i] = pqi[i];
        pqj[i] = (p[i] - q[i]);
        tpqj[i] = pqj[i];
    }
    sort(tpqi + 1, tpqi + 1 + n);
    sort(tpqj + 1, tpqj + 1 + n);
    for (int i = 1; i <= n; ++i)
        sumpqi[i] = sumpqi[i - 1] + tpqi[i], sumpqj[i] = sumpqj[i - 1] + tpqj[i];
    ll mxsum = 0;
    for (int i = 1; i <= n; ++i)
    {
        int posp = lower_bound(tpqi + 1, tpqi + 1 + n, pqi[i]) - tpqi;
        int posq = lower_bound(tpqj + 1, tpqj + 1 + n, pqj[i]) - tpqj;
        mxsum += abs(sumpqi[posp] - (posp) * pqi[i]) + abs(sumpqi[n] - sumpqi[posp] - (n - posp) * pqi[i]);
        mxsum += abs(sumpqj[posq] - (posq) * pqj[i]) + abs(sumpqj[n] - sumpqj[posq] - (n - posq) * pqj[i]); 
    }
    cout << sum - mxsum / 2 << endl;
    return 0;
}

posted @   YUGUOTIANQING  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示