diff --git a/solutions/CF739A.md b/solutions/CF739A.md new file mode 100644 index 0000000..57d96dc --- /dev/null +++ b/solutions/CF739A.md @@ -0,0 +1,39 @@ +# [CF739A Alyona and mex](https://www.luogu.com.cn/problem/CF739A) + +## 题意 + +给定 $m$ 个区间,构造出一个长度为 $n$ 的序列,使得这 $m$ 个区间的最小 $mex$ 最大。 $mex$ 定义为最小的没有出现过的自然数。 + +## 题解 + +先观察样例,发现两次输出的 $mex$ 均等于**最短的区间长度**,显然这不是巧合。 + +首先很容易得出 $mex(S) \le \lvert S \rvert$,且当 $S$ 覆盖 $0$ 到 $\lvert S \rvert - 1$ 时取等,所以最终答案不会超过最短的区间的长度,然后思考如何构造出答案等于最短区间长度的情况。 + +求出最短的区间长度为 $x$,只要让这个区间完全覆盖 $0, 1, 2, ..., x - 1$ ,就可以取到 $mex$ 的最大值,所以则只要在数组中循环填入 $0, 1, 2, ..., x - 1$,就能保证每一个长度大于等于 $x$ 的区间 $mex$ 一定都等于 $x$,因为每一个长度大于等于 $x$ 的区间都至少覆盖一次 $0, 1, 2, ..., x - 1$。(可以自己手搓几个样例试试) + +## 代码 + +```cpp +#include +using namespace std; +int main() +{ + int n, m; + scanf("%d%d", &n, &m); + int minlen = INT_MAX; + for (int i = 0; i < m; ++i) + { + int l, r; + scanf("%d%d", &l, &r); + minlen = min(minlen, r - l + 1); + } + printf("%d\n", minlen); + int cnt = 0; + for (int i = 1; i <= n; ++i) + printf("%d ", i % minlen); + return 0; +} +``` + +--- \ No newline at end of file