Description
给出一长度为 n n 的序列的 m m 个子序列,定义子序列 [l,r] [ l , r ] 的 mex m e x 值为自然数中不属于该子序列的最小值,要求构造 a a 序列使得这个子序列的 mex m e x 值最小值最大化
Input
第一行输入两个整数 n,m n , m 表示序列长度和子序列个数,之后 m m 行每行输入一个子序列的端点
Output
构造出 a a 序列使得这个子序列的 mex m e x 值最小值最大化,并输出该最大值
Sample Input
5 3
1 3
2 5
4 5
Sample Output
2
1 0 2 1 0
Solution
对于区间 [l,r] [ l , r ] ,其 mex m e x 值最大为 r−l+1 r − l + 1 ,即该区间的这 r−l+1 r − l + 1 个数需要是 0,1,...,r−l 0 , 1 , . . . , r − l 的一个排列,故这 m m 个子序列的值最小值最大只可能是 len=min(ri−li+1,1≤i≤m) l e n = m i n ( r i − l i + 1 , 1 ≤ i ≤ m ) ,现在证明最大值是可以取到的,只要把 a1,...,an a 1 , . . . , a n 构造为 0,1,...,len−1,0,1,...,len−1,... 0 , 1 , . . . , l e n − 1 , 0 , 1 , . . . , l e n − 1 , . . . 即可,这样对于给出的任一子序列,由于其长度不小于 len l e n ,该区间中 0,1,...,len−1 0 , 1 , . . . , l e n − 1 每个数字至少出现了一次,故其 mex m e x 值至少为 len l e n ,而对于最短的子序列去 mex m e x 值为 len l e n ,故此时答案为 mex m e x
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111111
int n,m,a[maxn],ans;
int main()
{
while(~scanf("%d%d",&n,&m))
{
int ans=n;
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
ans=min(ans,r-l+1);
}
printf("%d\n",ans);
for(int i=0;i<n;i++)printf("%d%c",i%ans,i==n-1?'\n':' ');
}
return 0;
}