大意: 给定m个区间, 求构造一个长n且字典序最小的序列, 使得每个区间内的数各不相同
求出每个位置为左端点时向右延伸最大距离, 然后双指针, 每次从set中取最小
#include <iostream> #include <algorithm> #include <math.h> #include <cstdio> #include <set> #include <map> #include <string> #include <vector> #include <string.h> #include <queue> #define PER(i,a,n) for(int i=n;i>=a;--i) #define REP(i,a,n) for(int i=a;i<=n;++i) using namespace std; const int N = 1e6+10; int n, m, a[N], ans[N]; set<int> s; void work() { scanf("%d%d", &n, &m); REP(i,1,n) a[i]=i; REP(i,1,m) { int l, r; scanf("%d%d", &l, &r); a[l] = max(a[l], r); } s.clear(); REP(i,1,n) s.insert(i); int now = 1; REP(i,1,n) { while (now<=a[i]) { ans[now++]=*s.begin(); s.erase(s.begin()); } s.insert(ans[i]); } REP(i,1,n) printf("%d%c",ans[i]," \n"[i==n]); } int main() { int t; scanf("%d", &t); while (t--) work(); }