有一根长度为 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 Ti≥Si)时刻会使得从第 L i − ( T i − S i ) L_i-(T_i-S_i) Li−(Ti−Si) 段到第 L i + ( T i − S i ) L_i+(T_i-S_i) Li+(Ti−Si) 段的传感器检测到水流。
求管道中每一段中间的传感器都检测到有水流的最早时间。
输入格式
输入的第一行包含两个整数 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
n≤200,
S
i
,
l
e
n
≤
3000
S_i,len ≤ 3000
Si,len≤3000;
对于
70
%
70\%
70% 的评测用例,
n
≤
5000
n ≤ 5000
n≤5000,
S
i
,
l
e
n
≤
1
0
5
S_i,len ≤ 10^5
Si,len≤105;
对于所有评测用例,
1
≤
n
≤
1
0
5
1 ≤ n ≤ 10^5
1≤n≤105,
1
≤
S
i
,
l
e
n
≤
1
0
9
1 ≤ S_i,len ≤ 10^9
1≤Si,len≤109,
1
≤
L
i
≤
l
e
n
1 ≤ L_i ≤ len
1≤Li≤len,
L
i
−
1
<
L
i
L_{i-1} < L_i
Li−1<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;
}