The 19th Zhejiang University City College Programming Contest H. Distance(思维)VP

我们可以按上图所画的方法算每个边的贡献。

如果答案点在线段上:贡献为x1 + x2

如果答案在线段外:贡献为x1 + x2 + x3 * 2

这里x3就是这道题要的贡献答案

我们会惊奇的发现这和原题所求的贡献之间的关系为:原题答案 = (上述答案 - 线段长度)/ 2.

现在题目所求的min值就是我们上面改编算贡献的答案的(min值-所有线段的长度)/ 2.

我们可以发现答案点的左边和右边的线段端点数一定相等。(这个性质用改编过后算贡献的方法比较好得出)。

所以我们用两个优先队列维护两边的端点数相等,算答案的方式挺多的大家可以自己试试。

这道题的难点就是要推出答案点左右端点数相等。

代码如下:

#include <bits/stdc++.h>
using namespace std;

#define ll long long 
#define edl '\n'

ll n,ans,l,r;

priority_queue<ll, vector<ll>, less<ll>> ql;
priority_queue<ll, vector<ll>, greater<ll>> qr;

void Solve()
{
    ans = 0;
    cin >> n;
    cin >> l >> r;
    ql.push(l);
    qr.push(r);
    cout << 0 << edl;
    for(int i = 2; i <= n; i++)
    {
        cin >> l >> r;
        if(r < ql.top())
        {
            ans += ql.top() - r;
            qr.push(ql.top());
            ql.pop();
            ql.push(l);
            ql.push(r);
        }
        else if(l > qr.top())
        {
            ans += l - qr.top();
            ql.push(qr.top());
            qr.pop();
            qr.push(l);
            qr.push(r);
        }
        else
        {
            ql.push(l);
            qr.push(r);
        }
        cout << ans << edl;
    }
}

int main()
{
    ios_base::sync_with_stdio(false), cin.tie(0);
    int t = 1;
    //cin >> t;
    while(t--)
        Solve();
    return 0;
}

题目链接:https://codeforces.com/gym/103660/problem/H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值