【hdu 6301】Distinct Values(区间)
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的最小数组,并且L到r里面不能有相等的数。输入中的n是数组的长度,m表示有m组L,r数据
思路:这道题要用到set和区间的知识点。主要思想是找一个指针,判断指针是否在区间内,若指针比区间的左界还小,说明指针指向的数对此区间无影响,此时就可以把这个数送回到set中。
My DaiMa:
#include<bits/stdc++.h>
//#include<set>
using namespace std;
const int Max = 1e5+5;
int main()
{
int pre[Max],a[Max],t,n,m,l,r;//pre用来记录区间的左界,数组a是要求的数组
while(~scanf("%d",&t))
{
while(t --)
{
scanf("%d%d",&n,&m);
for( int i = 1;i <= n;i ++) pre[i] = i;//定义每个的初始区间
while(m --)
{
scanf("%d%d",&l,&r);
pre[r] = min(pre[r],l);//更新输入的区间的左界
}
for(int i = n-1;i >= 1;i --) pre[i] = min(pre[i],pre[i+1]);//继续对每个区间的左界进行优化,其实这个for循环是用来更新pre[i]到i的每个区间的左界,因为上面输入的时候更新的只是i的区间左界
set<int> s;
for(int i = 1;i <= n;i ++) s.insert(i);//初始化set
int flag = 1;//flag用来与区间的左界进行比较
for(int i = 1;i <= n;i ++)
{
while(flag < pre[i])//如果flag比区间的左界还要小的话,说明flag指向的数对区间没有影响
{
s.insert( a[flag]);//就可以把flag所指向的数送回set里
flag++;//接着判断下一个
}
a[i] = *s.begin();//为了使最终的数组是最小数组,每次使用的都是set中的第一个数
s.erase(a[i]);//用完以后以免重复,要删除使用过的元素
}
for( int i = 1;i < n;i ++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}
}
}
最后附精美照片一枚