【HDU6301】Distinct Values(优先队列)

题目链接

Distinct Values

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4121    Accepted Submission(s): 1381


 

Problem Description

Chiaki has an array of n positive integers. You are told some facts about the array: for every two elements ai and aj in the subarray al..r (l≤i<j≤r ), ai≠aj holds.
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 T , indicating the number of test cases. For each test case:

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

It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106 .

 

Output

For each test case, output n 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

解题思路:

先按照区间的左端点进行从小到大排序,若左端点相等时,则按照右端点从大到小排序,这样排序后会出现2种需要考虑的情况。(若现区间的左右端点都落在上一个区间的左右端点内,则不需要考虑)

1.现区间的左端点大于上一区间的左端点,现区间的右端点大于上一区间的右端点,但两个区间没有重叠部分。

2.现区间的左端点大于上一区间的左端点,现区间的右端点大于上一区间的右端点,两区间有重叠部分。

维护一个优先队列,先将1-n的数都进入队列,然后只需遍历每一个区间。

例如10 3 [2  8]  [1  5]  [6  10]  的样例,把1 到 10 push进优先队列后,排序后先判断[1  5]  这个区间,所以先从优先队列里取 1 2 3 4 5,此时队列剩下6 7 8 9 10,下个区间 [2  8] ,我们先把[ 1  2 )这个区间也就是上次剩下的数丢到优先队列里面去。现在优先队列剩下 1 6 7 8 9 10 ,需要从里面取出8 - 5 个数,所以结果现在是1 2 3 4 5 1 6 7 。下个区间[ 6  10 ] ,丢[2   6)这个区间的数进优先队列,也就是 2  3  4  5 这四个数。再从这四个数取 10 - 8 个,所以答案是1 2 3 4 5 1 6 7 2 3

代码:

#include<bits/stdc++.h>
using namespace std;
int a[100005],ans[100005];
struct node{
	int a,b;
}b[100005];
bool cmp(node a,node b)
{
	return ((a.a==b.a)?a.b>b.b:a.a<b.a);
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
		int n,m;
		scanf("%d%d",&n,&m);
		priority_queue< int,vector<int>,greater<int> >q;
		while(!q.empty())q.pop();
		for(int i=0;i<m;i++)scanf("%d%d",&b[i].a,&b[i].b);
		sort(b,b+m,cmp);
		for(int i=1;i<=n;i++)q.push(i);
		for(int i=1;i<=n;i++)ans[i]=1;
		//for(int i=0;i<m;i++)printf("//%d %d\n",b[i].a,b[i].b);
		int t1=0,t2=0,p1=b[0].a,p2=b[0].a-1;
		for(int i=0;i<m;i++){
			if(b[i].a>t1 && b[i].b>t2){
				t1=b[i].a;
				t2=b[i].b;
				for(int j=p1;j<t1;j++)q.push(ans[j]);
				for(int j=p2+1;j<=b[i].b;j++){
					int x=q.top();
					q.pop();
					ans[j]=x;
				}			
			}
			p1=t1;
			p2=t2;
		} 
		printf("%d",ans[1]);
		for(int i=2;i<=n;i++)printf(" %d",ans[i]);
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/81368149