给出m个区间,每个区间内的数字不能有相等的,求字典序最小的结果序列.
排序区间后,维护区间端点,用set获得填的值.在遇到右端点(和当前队列顶部端点为同一区间)时补充set的值,这个过程是类似尺取的,只用n次.
注意细节即可.
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <queue>
#include <set>
#include <vector>
using namespace std;
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
typedef long long LL;
const int MAXN = 1e6 + 17;
const int MOD = 1e9 + 7;
struct dap
{
int p,ty,id;
dap(int a,int b,int c):p(a),ty(b),id(c){}
bool operator< (const dap & b) const
{
if(p==b.p)
return ty<b.ty;
return p<b.p;
}
};
int main(int argc, char const* argv[])
{
#ifdef noob
freopen("Input.txt", "r", stdin);
freopen("Output.txt", "w", stdout);
#endif
int t;
cin>>t;
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
vector<int > a(n+17),sur(n+17);
vector<dap > all[n+17];
set<int > s;
for (int i = 0; i < m; ++i)
{
int l,r;
scanf("%d%d",&l,&r);
sur[i] = 1;
all[l].push_back(dap(l,-1,i));
all[r].push_back(dap(r,1,i));
}
for (int i = 1; i <= n; ++i)
{
sort(all[i].begin(),all[i].end());
s.insert(i);
}
bool in = false;
queue<pair<int,int > > que;
for (int i = 1; i <= n; ++i)
{
if(all[i].size())
{
a[i] = *s.begin();
s.erase(a[i]);
for (int j = 0; j < all[i].size(); ++j)
{
int p = all[i][j].p,ty = all[i][j].ty,id = all[i][j].id;
if(ty==-1)
que.push({p,id});
else
{
if(!que.empty()&&que.front().second==id)
{
int st = que.front().first,ed = p;
bool nxt = false;
que.pop();
while(!que.empty())
{
if(sur[que.front().second])
{
nxt = true;
ed = que.front().first;
break;
}
else
que.pop();
}
debug(st);
if(nxt) ed--;
for (int k = st; k <= ed; ++k)
s.insert(a[k]);
}
else
sur[id] = 0;
}
}
if(que.size())
in = true;
else
in = false;
}
else
{
if(!in) a[i] = 1;
else
{
a[i] = *s.begin();
s.erase(a[i]);
}
}
}
for (int i = 1; i <= n; ++i)
{
printf("%d%c", a[i],i==n?'\n':' ');
}
}
return 0;
}