欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【hdu 6301】Distinct Values(区间)

程序员文章站 2022-06-09 18:58:18
...

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]);
        }
    }
}

最后附精美照片一枚

【hdu 6301】Distinct Values(区间)

 

相关标签: set 区间 多校