Distinct Values
Problem Description
Chiaki has an array of
n
n
positive integers. You are told some facts about the array: for every two elements and
aj
a
j
in the subarray
al..r
a
l
.
.
r
(
l≤i<j≤r
l
≤
i
<
j
≤
r
),
ai≠aj
a
i
≠
a
j
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 T , indicating the number of test cases. For each test case: The first line contains two integers and m m () – the length of the array and the number of facts. Each of the next m m lines contains two integers and ri r i ( 1≤li≤ri≤n 1 ≤ l i ≤ r i ≤ n ). It is guaranteed that neither the sum of all n n nor the sum of all exceeds 106 10 6 .
Output
For each test case, output n 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
题目概述
不同的值
问题描述
Chiaki有一个n元正整数数组。告诉您关于数组的一些事实:对于每两个元素和 aj a j 在子数组 al..r a l . . r ( l≤i<j≤r l ≤ i < j ≤ r ), ai≠aj a i ≠ a j 中。
Chiaki想找一个符合事实的字典上的最小数组。
输入
有多个测试用例。第一行输入包含一个整数 T T ,表示测试用例的数量。每个测试用例为:第一行包含两个整数n和m()———数组的长度和有几组 i i 和。接下来的 m m 行包含两个整数和 ri r i ( 1≤li≤ri≤n 1 ≤ l i ≤ r i ≤ n )。保证 n n 和都不超过 106 10 6 。
输出
对于每个测试用例,输出 n n 个整数,表示字典序上的最小数组。整数应该由一个单独的空间分隔,并且在行尾不允许有额外的空间。
样例输入
3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4
样例输出
1 2
1 2 1 2
1 2 3 1 1
思路
这道题意思是 要让输出的这个数组是最小的 且输入的每组和
j
j
<script type="math/tex" id="MathJax-Element-423">j</script>表示的是a数组中的第i个数到第j个数之间不能有重复的元素
例如 我们以最后一组数据来看
5 2
1 3
2 4
说明 a数组中有5个元素 有两组i和j
因此我们可以先吧a[1]到a[n]全赋初值为1.
设一个优先队列 从首部到尾部依次是 1,2,3…….n;
我们把每组i和j,以i从小到大的顺序排列(如果两组i相同,以j从小到大排列)
观察当前组中从第i个数到第j个数中是否存在已被更新过的
如果存在被更新过的
那么将上组数据中与改组数据中未重合的部分返回优先队列即可 将该组数中与上一组数中未重合的部分 输入优先队列首部数即可
如果不存在被更新过的
则将上组数据全部返回优先队列 再输入优先队列首部数即可
代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
struct node
{
int l,r;
}a[100005]; //设一结构体存每组i,j
int ans[100005];
int cmp(node a,node b) //结构体的sort排序
{
if(a.l==b.l) //如果两组i相同,以j从小到大排列
return a.r<b.r;
return a.l<b.l; //以i从小到大的顺序排列
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
priority_queue <int, vector<int>, greater<int> > q;//优先队列 从小到大排
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; //将组初值都附为1
q.push(i); //优先队列 从首部到尾部依次是 1,2,3.......n
}
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();
}
l=a[i].l;
r=a[i].r;
}
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();
}
l=a[i].l;
r=a[i].r;
}
}
for(int i = 1; i <= n; i++)
if(i == n)
printf("%d\n", ans[i]);
else
printf("%d ", ans[i]);
}
return 0;
}