Description
要求构造一个字典序最小的序列 a1,...,an a 1 , . . . , a n 使得所给的 m m 个区间中的数字各不相同
Input
第一行一整数表示用例组数,每组用例首先输入两个整数 n,m n , m 表示序列长度和要求个数,之后 m m 行每行输入两个整数表示 al,...,ar a l , . . . , a r 需互不相同
(1≤n,m≤105,∑n,∑m≤106) ( 1 ≤ n , m ≤ 10 5 , ∑ n , ∑ m ≤ 10 6 )
Output
输出满足条件的字典序最小的序列
Sample Input
3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4
Sample Output
1 2
1 2 1 2
1 2 3 1 1
Solution
贪心,不在所给区间中的位置显然放 1 1 ,之后拿优先队列维护当然可以使用的数字,每次取最小的出来放入当前考虑的位置即可,时间复杂度
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef pair<int,int>P;
#define maxn 100005
int T,n,m,ans[maxn];
P a[maxn];
#define L first
#define R second
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)scanf("%d%d",&a[i].L,&a[i].R);
sort(a,a+m);
priority_queue< int,vector<int>,greater<int> >que;
for(int i=1;i<=n;i++)que.push(i),ans[i]=1;
int l=1,r=0;
for(int i=0;i<m;i++)
{
int tl=max(r+1,a[i].L);
int tr=min(r,a[i].L-1);
for(int j=l;j<=tr;j++)que.push(ans[j]);
for(int j=tl;j<=a[i].R;j++)
ans[j]=que.top(),que.pop();
l=a[i].L,r=max(r,a[i].R);
}
for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}