传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6301
题意就是给出一些区间,要求你构造一个数列满足这些区间里的数两两不相同,同时数列满足字典序最小。
解法:就是题意【听了想打人。。。。】然而具体操作GG
首先构造数组pre[i]表示第i个位置要和最前头哪个范围里的数不相同
之后用set维护可选的数字,用pl保存左端的位置,当填下一个位置的pre[i]值大于pl时说明pl到pre[i]之间的值又可以选了把他们加到set里来
#include<bits/stdc++.h>
using namespace std;
int pre[100009],ans[100009];
int l,r,t,n,m;
set<int>val;
int main()
{ scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
val.clear();
for (int i=1;i<=n;i++)pre[i]=i,val.insert(i);
for (int i=1;i<=m;i++)
{scanf("%d%d",&l,&r);
if (pre[r]>l)pre[r]=l;
}
for (int i=n-1;i>=1;i--)
if (pre[i+1]<pre[i])pre[i]=pre[i+1];
int pl=1;
for (int i=1;i<=n;i++)
{ while(pl<pre[i])
{ val.insert(ans[pl]);
pl++;
}
ans[i]=*val.begin();
val.erase(ans[i]);
}
printf("%d",ans[1]);
for (int i=2;i<=n;i++)printf(" %d",ans[i]);
printf("\n");
}
return 0;
}