区间合并——下水道(蓝桥杯)

有一根长度为 l e n len len 的横向的管道,该管道按照单位长度分为 l e n len len 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。

一开始管道是空的,位于 L i L_i Li 的阀门会在 S i S_i Si 时刻打开,并不断让水流入管道。

对于位于 L i L_i Li 的阀门,它流入的水在 T i T_i Ti T i ≥ S i T_i \ge S_i TiSi)时刻会使得从第 L i − ( T i − S i ) L_i-(T_i-S_i) Li(TiSi) 段到第 L i + ( T i − S i ) L_i+(T_i-S_i) Li+(TiSi) 段的传感器检测到水流。

求管道中每一段中间的传感器都检测到有水流的最早时间。

输入格式

输入的第一行包含两个整数 n , l e n n,len n,len,用一个空格分隔,分别表示会打开的阀门数和管道长度。

接下来 n n n 行每行包含两个整数 L i , S i L_i,S_i Li,Si,用一个空格分隔,表示位于第 L i L_i Li 段管道中央的阀门会在 S i S_i Si 时刻打开。

输出格式

输出一行包含一个整数表示答案。

数据范围

对于 30 % 30\% 30% 的评测用例, n ≤ 200 n ≤ 200 n200 S i , l e n ≤ 3000 S_i,len ≤ 3000 Si,len3000
对于 70 % 70\% 70% 的评测用例, n ≤ 5000 n ≤ 5000 n5000 S i , l e n ≤ 1 0 5 S_i,len ≤ 10^5 Si,len105
对于所有评测用例, 1 ≤ n ≤ 1 0 5 1 ≤ n ≤ 10^5 1n105 1 ≤ S i , l e n ≤ 1 0 9 1 ≤ S_i,len ≤ 10^9 1Si,len109 1 ≤ L i ≤ l e n 1 ≤ L_i ≤ len 1Lilen L i − 1 < L i L_{i-1} < L_i Li1<Li

输入样例:
3 10
1 1
6 5
10 2
输出样例:
5
#include <bits/stdc++.h>
#define x first
#define y second
#define int long long

using namespace std;

const int N = 1e5 + 10;
typedef pair<int, int> PII;
int n, m;
PII s[N], q[N];

bool check(int u)
{
    int cnt = 0;
    for(int i = 0; i < n; i ++ )
    {
        int L = s[i].x, S = s[i].y;

        if(S <= u) // 当前时刻u大于等于水阀打开时刻S
        {
            int t = u - S;
            int l = max((int)1, L - t), r = min(m, L + t); // 水在u时刻所能覆盖的范围
            q[cnt ++ ] = {l, r};
        }
    }

    sort(q, q + cnt);

    int l = -1, r = -1;
    for(int i = 0; i < cnt; i ++ )
    {
        if(q[i].x <= r + 1) r = max(r, q[i].y); // 合并u时刻水覆盖的区域
        else l = q[i].x, r = q[i].y;
    }
    return l == 1 && r == m;
}

signed main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i ++ ) cin >> s[i].x >> s[i].y;

    int l = 0, r = 2e9;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }

    cout << l << endl;
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值