D. Jumping Through Segments

https://codeforces.com/contest/1907/problem/D

题意:n个区间,从[0, 0]开始跳跃,每次跳跃的步长不能超过k,并且第i次跳跃的落脚点必须在第i个区间范围内,求最小k是多少。

思路:一眼二分,范围是[0, 1e9],维护一个当前可以达到的区间端点,然后看每次操作是否都能落在区间内即可。

总结:直接从第0个块开始判定,不需要先手动设置第0个块的范围,手动设置容易出错。其次更新当前区间可达端点,只要求并集即可,不需要判定什么左边右边,哪个大哪个小,如何比较。

inline void solve() {
	int n;
	cin >> n;

	vector<pair<int, int>> seg(n);
	for (auto& [x, y] : seg) {
		cin >> x >> y;
	}

	auto valid = [&](long long x) {
		long long l = 0, r = 0;
		for (int i = 0; i < n; ++i) {
			if (seg[i].second < l - x || seg[i].first > r + x) {
				return false;
			}
			l -= x;
			l = max(0ll, l);
			r += x;
			l = max<long long>(l, seg[i].first);
			r = min<long long>(r, seg[i].second);
		}
		return true;
	};

	long long l = 0, r = 1e9 + 19;
	while (l < r) {
		long long mid = (l + r) >> 1;
		if (valid(mid)) {
			r = mid;
		}
		else {
			l = mid + 1;
		}
	}

	cout << l << '\n';
}
posted @ 2025-04-10 09:37  _Yxc  阅读(16)  评论(0)    收藏  举报