2018 Multi-University Training Contest 1 Distinct Values (优先队列)

Distinct Values

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


 

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≠ajholds.
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

 

题目大意:给你n个点和m个区间,在m个区间里面,所在区间不能有重复的数字,并使得整个数列最小化,比如输入n:5(既有五个点),m:2(有两个区间不能有重复的数字出现),接下来m行:(1,3)、(2,4)既1到3和2到4这两个区间不能有重复的数字出现,既得输出样例为:1 2 3 1 1

题解:先建立一个结构体,储存m个区间,再对左区间进行升序排序,如果左区间相等,就对右区间降序排序(可以理解为区间的长度进行降序排序,因为在循环是,如果一个区间比上个区间还小的话,直接continue),然后建立一个优先队列(数值小的先出),先将1到n的数字放进队列,再对每个区间进行判断,如果该区间的右区间比上个左区间小的话,跳过该循环,否则则有两种情况:1.该区间与上个区间有交集(为保持最小,将队列放入上个区间的左区间到该区间的左区间-1的数字放入队列,再将这些数字放入交集的后半部分)。2.该区间与上个区间不存在交集(则将上个区间的数字全部放进队列,再对该区间进行填写)。(先将整个数组初始化为1),这样就能保持最小的情况了。

代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int first,last;
}go[100006];
int out[100006];
bool cmp(node a,node b){ //排序 
	if(a.first==b.first){
		return a.last>b.last;
	}
	return a.first<b.first;
}
priority_queue<int,vector<int>,greater<int> >q;//创建优先队列 
int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d %d",&n,&m);
		while(!q.empty()){
			q.pop();
		}
		for(int i=1;i<=n;i++){
			q.push(i);
			out[i]=1;
		}
		for(int i=0;i<m;i++){
			scanf("%d %d",&go[i].first,&go[i].last);
		}
		sort(go,go+m,cmp);
		int test=1;
		for(int i=0;i<m;i++){
			if(i==0){
				for(int j=go[i].first;j<=go[i].last;j++){
					out[j]=q.top();
					q.pop();
				}
			}
			else{
				if(go[i].last<=go[i-test].last){
					test++;						//如果该上个区间包含该区间直接跳过				
					continue;
				}
				for(int j=go[i-test].first;j<=min(go[i].first-1,go[i-test].last);j++){	//进行判断两种情况 
					q.push(out[j]);		
				}
				for(int j=max(go[i-test].last+1,go[i].first);j<=go[i].last;j++){
					out[j]=q.top();
					q.pop();
				}	
			}
			test=1;
		}
		for(int i=1;i<=n;i++){
			printf("%d",out[i]);
			if(i==n)
			printf("\n");
			else
			printf(" ");
		}
	
	}
}
发布了13 篇原创文章 · 获赞 4 · 访问量 4203

猜你喜欢

转载自blog.csdn.net/yiyiLy/article/details/81185452