2018HDU多校训练一 D Distinct Values

hiaki has an array of nn positive integers. You are told some facts about the array: for every two elements aiai and ajaj in the subarray al..ral..r (l≤i Chiaki would like to find a lexicographically minimal array which meets the facts. 

Input

There are multiple test cases. The first line of input contains an integer TT, indicating the number of test cases. For each test case: 

The first line contains two integers nn and mm (1≤n,m≤1051≤n,m≤105) -- the length of the array and the number of facts. Each of the next mm lines contains two integers lili and riri (1≤li≤ri≤n1≤li≤ri≤n). 

It is guaranteed that neither the sum of all nn nor the sum of all mm exceeds 106106. 

Output

For each test case, output nn integers denoting the lexicographically minimal array. Integers should be separated by a single space, and no extra spaces are allowed at the end of lines. 

Sample Input

3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4

Sample Output

1 2
1 2 1 2
1 2 3 1 1

题意:给你n组数,没每组有L,R两个数,数组a[n],L ~ R区间内的正整数各部相同,让你输出字典序最小的数组;

题解:先将这些组数据按L1R2 的优先级排序,可以用set 维护还可以用的数字有哪些,开始将1~n全部加入到set中,然后从1  erase去第一个node 的r-1个数字,然后,令ll 为node[1].l rr为node[1].r,对于后面的node分3中情况:

1.如果node[i].r <= r,说明这个区间已经更新过了,且满足字典序最小,数字不同

2.如果node[i].l>r,则为一个新的开始,将a[l]~a[r]的数字加入到set里面,就从set.begin()开始 将*set.begin()赋值给a[node[i].l]到a[node[i].r],每赋值一个,set就删除一个,更新l,r的值

3.如果node[i].l<=r,则和上面2类似,就是区间变为 r~node[i].r;

参考代码为:

#include
using namespace std;
typedef long long LL;
const LL inf=0x3f3f3f3f3f3f3f3fLL;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int T,n,m,flag[maxn];
struct Node{
	int l,r;
	bool operator < (const Node&b) const 
	{
		return l==b.l? r>b.r : l s1;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		s1.clear();
		memset(flag,0,sizeof flag);
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) s1.insert(i);
		for(int i=1;i<=m;i++) scanf("%d%d",&node[i].l,&node[i].r);
		sort(node+1,node+1+m);
		for(int i=node[1].l,j=1;i<=node[1].r;i++,j++) s1.erase(j),flag[i]=j;
		int l=node[1].l,r=node[1].r;
		for(int i=2;i<=m;i++)
		{
			if(node[i].r<=r) continue;
			if(node[i].l>r)
			{
				for(int k=l;k<=r;k++) s1.insert(flag[k]);
				for(int k=node[i].l;k<=node[i].r;k++) flag[k]=*s1.begin(),s1.erase(flag[k]);
				l=node[i].l,r=node[i].r;
			}
			else
			{
				for(int k=l;k

 

你可能感兴趣的:(贪心,XJBX)