题意:
有 n 个数 m 个区间,n个数均为正整数,求满足在这m个区间中各自没有重复的数字的序列,并且这个序列的字典序要最小。
因为要字典序最小,所以每次取就取最小的且当前在这个区间中没出现过的。
利用一个优先队列来存放当前还没放出去的数字,队头就是要放的数。
然后每次到下一个区间要把该区间之前的放出去的数回收到队列里,就是这么一个过程就可以得到答案了。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long int LL;
const int maxn = 1e5 + 10;
int T, n, m, ans[maxn];
priority_queue<int, vector<int>, greater<int> > q;
struct node{
int l, r;
bool friend operator < (node a, node b){
return a.l < b.l;
}
}a[maxn];
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d",&a[i].l, &a[i].r);
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) q.push(i);
int be = 1, ed = 1;
sort(a+1, a+1+m);
for(int i=1;i<=m;i++){
while(ed < a[i].l) ans[ed++] = 1;
while(be < a[i].l) {
if(ans[be] != 1 || q.top() != 1) q.push(ans[be]);
be ++;
}
while(ed<=a[i].r){
ans[ed ++] = q.top();
q.pop();
}
}
while(ed<=n) ans[ed++] = 1;
for(int i=1;i<=n;i++) {
if(i-1) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}