1 条题解
-
0
思路
序言
其实这道题实现起来并不难,只是思路有些不好想。
说说思路
我们定义一个 数组, 表示以 为右端点, 的最大值。再用一个 记录答案,我们使 ,在 中,不断更新 ,则 。
解释一下吧
为什么要这么预处理?
表示为左端点必须至少为 ,才能避免包含任何以 为右端点的给定区间。因为如果左端点不大于 ,那么区间 就会被包含。取 是为了得到严格大于所有左端点的最小值,取最大值是为了处理多个区间重叠的情况,保证合法。
为什么 要这样算 ?
因为要保证不要重复计算情况数。使 ,这样 就保证了所有右端点不大于 的给定区间都不会被包含。
复杂度分析
- 时间复杂度:预处理读入 个区间,更新 数组,;扫描右端点 次,每次 ,总复杂度 。
- 空间复杂度: 数组大小为 ,即 。
代码实现
#include <bits/stdc++.h> using namespace std; int n, m, a[200005]; long long ans; int main() { cin >> n >> m; for (int i = 1, l, r; i <= n; i++) { cin >> l >> r; a[r] = max(a[r], l + 1); // 记录以 r 为右端点的最大左端点+1 } for (int r = 1, l = 1; r <= m; r++) { l = max(l, a[r]); // 更新左端点下限 ans += r - l + 1; // 累加以 r 为右端点的合法区间个数 } cout << ans << endl; return 0; }提示
十年 一场空,不开 long long 见祖宗。
- 1
信息
- ID
- 7911
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 34
- 已通过
- 8
- 上传者