Distinct Values
题意:题目要求构造一个长度为n的数组,要求在区间[l, r]中不能有重复数字,且数组中数必须是正整数,[l, r]这样的区间有多个,且有可能重叠;写出构造出来的字典序最小的数组;
思路:普通做法是把区间排序后遍历区间,未使用的数字标记,对后面没有影响的就再消除标记;
但是区间有很多,遍历每个区间会超时;
我们可以把区间放在数组上,存下以i为左端点的区间最多影响到的最右边的下标,set存没用过的数字,这样从头到尾遍历一遍数组就可以了;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
set<int> se;
int ans[maxn], pos[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
int n, m;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) pos[i]=i;
for(int i=0; i<m; i++){
int l, r;
scanf("%d%d", &l, &r);
pos[l]=max(pos[l], r);
}
se.clear();
for(int i=1; i<=n; i++) se.insert(i);
int _begin=1, _end=0;
for(int i=1; i<=n; i++){
if(_end>pos[i]) continue;
while(_begin<i) se.insert(ans[_begin++]);
while(_end<pos[i]){
ans[++_end]=*se.begin();
se.erase(ans[_end]);
}
}
for(int i=1; i<=n; i++){
printf("%d%c", ans[i], i==n?'\n':' ');
}
}
return 0;
}