Distinct ValuesTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
| |
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.
| |
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:
| |
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
|
题意: 已知一段长度为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;
}