hdu6301(贪心+set)

求一个长度为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;
}

猜你喜欢

转载自blog.csdn.net/bpdwn2017/article/details/81177295