求一个长度为n的数列, 给出m个区间,这m个区间各自区间内的数不同
当时比赛打完3题后稍微看了一下这题想了几分钟不是很容易就丢了。。比完想补这题想了一个垃圾做法复杂度有点高不敢写,于是面向标程编程了。。。大佬的做法真的清奇唉慢慢学吧
预处理一下用一个数组保存以这个点为起点的查询的最大的R的位置last[l] = max(last[l],r) (这里相当于去掉了完全包含在大区间里的小区间,因为包含在大区间里的小区间是完全没用的直接丢掉),没有查询的话就last[i] = i
唉思路不是很好用语言描述(大佬的做法真的太神了。。)直接看代码更容易懂。。。。
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <queue>
using namespace std;
const int mx = 1e5+7;
int last[mx];
int ans[mx];
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n, m;
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++)
last[i] = i;
int l, r;
for (int i = 1; i <= m; i++)
{
scanf("%d%d",&l,&r);
last[l] = max(last[l],r);
}
set <int> vis;
for (int i = 1; i <= n; i++) vis.insert(i);
l = 1, r = 0;
for (int i = 1; i <= n; i++)
{
if (r > last[i]) continue;
while (l < i)
{
vis.insert(ans[l]);
l++;
}
while (r < last[i])
{
ans[++r] = *vis.begin();
vis.erase(ans[r]);
}
}
for (int i = 1; i <= n; i++)
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}