有一根长度为 \(len\) 的横向的管道,该管道按照单位长度分为 \(len\) 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。
一开始管道是空的,位于 \(L_i\) 的阀门会在 \(S_i\) 时刻打开,并不断让水流入管道。
对于位于 \(L_i\) 的阀门,它流入的水在 \(T_i\)(\(T_i \ge S_i\))时刻会使得从第 \(L_i-(T_i-S_i)\) 段到第 \(L_i+(T_i-S_i)\) 段的传感器检测到水流。
求管道中每一段中间的传感器都检测到有水流的最早时间。
输入格式
输入的第一行包含两个整数 \(n,len\),用一个空格分隔,分别表示会打开的阀门数和管道长度。
接下来 \(n\) 行每行包含两个整数 \(L_i,S_i\),用一个空格分隔,表示位于第 \(L_i\) 段管道中央的阀门会在 \(S_i\) 时刻打开。
输出格式
输出一行包含一个整数表示答案。
数据范围
对于 \(30\%\) 的评测用例,\(n ≤ 200\),\(S_i,len ≤ 3000\);
对于 \(70\%\) 的评测用例,\(n ≤ 5000\),\(S_i,len ≤ 10^5\);
对于所有评测用例,\(1 ≤ n ≤ 10^5\),\(1 ≤ S_i,len ≤ 10^9\),\(1 ≤ L_i ≤ len\),\(L_{i-1} < L_i\)。
输入样例:
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;
}
标签:10,int,阀门,mid,len,蓝桥,管道
From: https://www.cnblogs.com/lint-ss/p/18086029