Distinct Values HDU - 6301
先感谢下在B站直播讲题的清华大佬。ˋ( ° ▽、° )
题目:
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
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≤10e5) – 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 10e6.
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
题面意思:
有t组样例,有个n长度的数组和m组限制。每一组限制输入为 l 和 r ,在数组 l 下标到 r 下标的范围内不能有重复数字。
思路:
算法是贪心。
每次输入l 和 r 时,把r 下标的数组数据改为 l。m组限制输入完毕后,从设置的下标数组从后往前比较,倒数第二个和倒数第一个比较,一直遍历到第一个。这样就能把每个最后要限制的不同的范围的数据改为l 的下标。然后利用set默认从小到大排序的便利,先初始化set(从1到n),每个范围内开始遍历每次有可以用的数据就从set中提出并erase去除。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
using namespace std;
const int SIZE = 1e5+5;
int pre[SIZE];
int arr[SIZE];
set<int> s;
int main() {
int t;
scanf("%d", &t);
while(t--) {
int m, n, l, r;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
pre[i] = i;
}
for(int i = 0; i < m; i++) {
scanf("%d%d", &l, &r);
pre[r] = min(l, pre[r]);
}
for(int i = n-1; i >= 1; i--) {
pre[i] = min(pre[i], pre[i+1]);
}
s.clear();
for(int i = 1; i <= n; i++) {
s.insert(i);
}
int js = 1;
for(int i = 1; i <= n; i++) {
while(js < pre[i]) {
s.insert(arr[js]);
js++;
}
arr[i] = *s.begin();
s.erase(arr[i]);
}
for(int i = 1; i <= n; i++) {
printf("%d", arr[i]);
printf("%c", i == n ? '\n' : ' ');
}
}
return 0;
}