题目链接
不想跳转链接的也可以直接滑到页面最底下
算法:差分
分析:
对原问题进行抽象, 可以简单的描述为一组序列在r个约束条件下能够每个元素能达到的最大值, 限制条件具体概述为开区间(a, b)中的每一个数<min(a, b)。
不同的约束关系之间有两种关系, 嵌套和交叉
交叉:有a<b<c<d, 其中(a, c)是一组约束条件, (b, d)是另一组约束条件。
分析可知开区间(a, c)中的所有元素<min(a, c), 开区间(b, d)中的所有元素<min(b, d), 其中推断有b<min(a, c), 与(b, d)中的所有元素<min(b ,d)矛盾, 由此可以知道, 约束条件不存在交叉关系
嵌套:有a<b<c<d, 其中(a, d)为一组, (b, c)为一组, 很容易知道, 可以轻易满足开区间(a, d)中的所有元素<min(a, d), 开区间(b, c)中的所有元素<min(b, c)
其实还有一种”相接“的关系, 即a<b<c, (a, b)和(b, c), 由最终通过了测试可知道, 不影响作答
考虑到维护的是数组区间, 且更大范围的约束条件包裹小范围的约束条件时, 需要保证小约束条件间相对高度不变, 所以这里维护差分数组是很好的选择。笔者当时写这题更多想的是维护区间所以用的差分数组
为了使序列尽可能的大, 又不让它超过最高h, 选择让序列初始值为h
小细节:题目提到了约束条件可能会重复,重复对同一个约束条件约束区间, 会使序列过小, 所以我们还需要去重
下面给出代码
#include <iostream>
#include <vector>
#include <algorithm>
const int maxn = 1e4 + 10;
int n, i, h, r, a[maxn];
int main()
{
//平平无奇的读入数据
std::cin >> n >> i >> h >> r;
std::vector<std::pair<int, int>>vec(r + 10, { 0, 0 });
for (int i = 1; i <= r; ++i)
{
std::cin >> vec[i].first >> vec[i].second;
//因为要对数据去重, 所以约束条件(a, b)最好是a<b
//这里对数据作一下预处理
if (vec[i].first > vec[i].second)
std::swap(vec[i].first, vec[i].second);
}
//下面是普通的排序+去重
std::sort(vec.begin() + 1, vec.begin() + r + 1, [](
std::pair<int, int>a, std::pair<int, int>b)->bool
{
if (a.first != b.first) a.first < b.first;
return a.second < b.second;
});
r = std::unique(vec.begin() + 1, vec.begin() + 1 + r, [](
std::pair<int, int>a, std::pair<int, int>b)->bool
{
return (a.first == b.first && a.second == b.second);
}) - (vec.begin() + 1);
a[1] += h;//另差分数组a[1]=h, 这样序列初值就为h了
for (int i = 1; i <= r; ++i)
{
//有约束条件(a, b), 那么需要对区间开区间(a, b)所有值减去1
//以满足约束条件的最低要求
int l = vec[i].first + 1, r = vec[i].second;
--a[l], ++a[r];
}
//朴实无华的输出
int num = 0;
for (int i = 1; i <= n; ++i)
{
num += a[i];
std::cout << num << '\n';
}
return 0;
}
----------------------------------------------------------------------------------
【题目描述】
FarmerJohn 有n头牛,它们按顺序排成一列。FarmerJohn 只知道其中最高的奶牛的序号及它的高度,其他奶牛的高度都是未知的。现在 FarmerJohn 手上有 R R R 条信息,每条信息上有两头奶牛的序号( a a a 和 b b b),其中 b b b 奶牛的高度一定大于等于 a a a 奶牛的高度,且 a , b a, b a,b之间的所有奶牛的高度都比 a a a 小。现在 FarmerJohn 想让你根据这些信息求出每一头奶牛的可能的最大的高度。(数据保证有解)
【输入格式】
第一行:四个以空格分隔的整数: n , i , h , R n, i, h, R n,i,h,R( n n n 和 R R R 意义见题面; i i i 和 h h h 表示第 i i i 头牛的高度为 h h h,他是最高的奶牛)
接下来 R R R 行:两个不同的整数 a a a 和 b b b( 1 ≤ a , b ≤ n 1 \le a, b \le n 1≤a,b≤n)
【输出格式】
一共 n n n 行,表示每头奶牛的最大可能高度.
【数据范围】
1 ≤ n ≤ 10000 1 \le n \le 10000 1≤n≤10000, 1 ≤ h ≤ 1000000 1 \le h \le 1000000 1≤h≤1000000, 0 ≤ R ≤ 10000 0 \le R \le 10000 0≤R≤10000
样例 #1
样例输入 #1
9 3 5 5
1 3
5 3
4 3
3 7
9 8
样例输出 #1
5
4
5
3
4
4
5
5
5