Distinct Values(优先队列 模拟)

Distinct Values

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

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

题意: 已知一段长度为n的数,从li->ri(li<=ri)都不相同,在满足所有li-ri的情况下求出这个序列的字典序最小的解。

①li到ri依次出队列并且赋值。

②把上一次赋的并且在当前li之前的值重新入队列。

我的思路是先对所有的li、ri从小到大排序,然后用优先队列存下从1-n的数,然后②①,②①,②①.......执行m次

所有相邻的li到ri分成3种情况:

①li-1、ri-1和li、ri没有公共部分

②li-1、ri-1和li、ri相交

③li、ri在li-1r、i-1内部

第三种情况不用管直接跳过。①和②赋值和入队列的左右端点都不相同。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct node{
	int l, r;
}a[100005];
int ans[100005];
int cmp(node x, node y){
	if(x.l == y.l)
		return x.r < y.r;
	return x.l < y.l;
}
int main()
{
	int T;
	while(scanf("%d", &T) != EOF){
		while(T--){
			priority_queue <int, vector<int>, greater<int> > q; 
			int n, m;
			scanf("%d%d", &n, &m);
			for(int i = 0; i < m; i++)
				scanf("%d%d", &a[i].l, &a[i].r);
			sort(a, a + m, cmp);
			for(int i = 1; i <= n; i++){
				ans[i] = 1;
				q.push(i);
			}
			int l = 1, r = 0;
			for(int i = 0; i < m; i++){
				if(a[i].l > r){
					for(int j = l; j <= r; j++){
						q.push(ans[j]);
					}
					for(int j = a[i].l; j <= a[i].r; j++){
						ans[j] = q.top();
						q.pop();
					}
					r = a[i].r;
					l = a[i].l;
				}
				else if(a[i].r > r){
					for(int j = l; j < a[i].l; j++){
						q.push(ans[j]);
					}
					for(int j = r + 1; j <= a[i].r; j++){
						ans[j] = q.top();
						q.pop();
					}
					r = a[i].r;
					l = a[i].l;
				}
			}
			for(int i = 1; i <= n; i++)
				if(i == n)
					printf("%d\n", ans[i]);
				else
					printf("%d ", ans[i]);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sxh759151483/article/details/81177903
今日推荐