CodeForces

来源:互联网 发布:什么是淘宝订购参谋 编辑:程序博客网 时间:2024/06/01 09:27
/*  这题是属于值得重做,且题意比较难理解的类型    简单解释下我理解的题意:    输入数据:  n(需要输出的序列的元素个数)、m ( subarray 的个数 )  后面的 m 行分别表示 m 个 subarray的起止元素下标 (且下标从1开始)    subarray:子序列,给出的 l 和 r 表示 1 个区间,从 a[l], a[l+1] .... a[r-1],a[r]  其实也就是把一个 array中,下标范围为 [l,r]的元素都取出来,单独称为是 subarray    题目要求:  对于某一序列的 m 个 subarray 的 m 个 mex, 如果我们取其中 mex 最小的值,记作 min_mex    现在要求,输出 1 个有 n 个元素的序列,使得它的 min_mex 的值尽可能大    mex:集合 S 的 mex,为 S 在整数集中的补集中最小的非负整数    对样例的分析可看这篇博客:  http://blog.csdn.net/sinat_35121480/article/details/53319149   上面的博客还有些没有提到,但是也值得说明的地方:    至于为什么要从 0 取到(Min-1),然后重新开始从 0 到 (Min-1) 这样构造序列,我不知道怎么用理论来论证,但是,可以确定的是,如果这样构造,那么在最长的那个子序列里,0到(Min-1)中的每个元素,肯定是出现且仅出现一次,刚好满足了 m 个min_mex 的值尽可能大    而如果不从0 到 (Min-1) 这样“连续”地取,那么中间肯定会出现某个间断点,这个间断点上,是某个比 (Min-1) 的数值还要小的元素    而按照 mex 的定义,“为 S 在整数集中的补集中最小的非负整数”,可知mex肯定是往小的方向去取,就肯定会取到这个断点而不是 Min    而这样局部推广到整体(也就是由一个序列的mex,推理到我们求的 m 组序列的 mex)以后,我们取到的 m 组mex的最小值 (即m组数据的 min_mex),也肯定会比“连续”地取时取得更小,那就不符合我们要求 min_mex 尽可能大的这一要求了    感受:  1.   以为的懂了,并不一定是真的懂了,我觉得我大概理解了这题大意,然而用文字描述大意的过程,仍然觉得很吃力    2.  现在突然觉得写题解也是一个比较吃力的过程,尤其是自己也有点迷迷糊糊、一知半解的题目    然而,整理这种题目的题解,却也十分有意义,会反向逼迫自己一定要弄得一清二楚,不能留有任何盲点,也可以让自己的思路变得清晰,印象也更加深刻    3.  越来越觉得 ACM 真的很有 “言有尽而意无穷”的韵味了,想想20+行的代码里,居然可以是那么久的思考量,就觉得这样积累起来的代码量,真的可以让自己思考问题更加深刻严谨和全面    突然想起以前是觉得 ACM 的代码既简洁无比又逻辑清晰,让人感觉这样的代码相当“优雅”(在我眼里,简洁即优雅),现在突然发现它还有另一个让人喜欢的地方,就是单位代码量的思考量也比较大,丝毫不用担心自己积累的代码量有多少水分... T^T*/


#include <iostream>#define rep(i, k, n) for (int i = k; i < (n); i++)using namespace std;const int INF = 0x3f3f3f3f;const int N = 1e5 + 10;int main(){int n, m, a[N][2];cin >> n >> m;int Min = INF;rep(i, 0, m){cin >> a[i][0] >> a[i][1];Min = min(Min, a[i][1] - a[i][0] + 1); //找到最小区间长度 }int tp = 0; //tp::temp,因为要求数组元素非负,且要求几个区间的最小mex最大,因而构造的序列需要从 0 开始cout << Min << endl;rep(i, 0, n){cout << tp++ << " ";if (tp == Min) tp = 0;} return 0;}


原创粉丝点击