hdu-多校联赛6301 Distinct Values

版权声明:本文为博主原创文章,转载请注明。 https://blog.csdn.net/qq_41181881/article/details/81265324

题目链接

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≠ajholds.
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

题目大意:

输入一个T,表示T组测试样例;再输入n,m表示一共n个数,m个区间。每个区间内的数不能相同,最小为1,整数增加。

输出总和最小的数列。

大体思路:

pre数组记录每个区间,数组下标代表区间末端,数组内存的是区间前端;flag当做判断指针;将区间前的数全部返回到set内(自动排序),a数组存最终答案;(代码内详细解释)

代码:

#include<bits/stdc++.h>
using namespace std;
int pre[1000005],a[1000005];
int main()
{
    int t,n,m,l,r;
    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);//记录区间的左端点(r代表末端点,pre数组内存的数代表左端点)
        }
        for(int i = n-1;i >= 1;i --)
            pre[i] = min(pre[i],pre[i+1]);//
        set<int> s;//插入后自动默认从小到大排序
        for(int i = 1;i <= n;i ++)
        {
            s.insert(i);//赋初值
        }
        int flag = 1;
        for(int i = 1;i <= n;i ++)
        {
            while(flag < pre[i])//将这个区间前的数全部返回
            {
                s.insert( a[flag]);//添加
                flag++;
            }
            a[i] = *s.begin();//a调用set内最小的数
            s.erase(a[i]);//存到a数组后就删除
        }
        for( int i = 1;i < n;i ++)
            printf("%d ",a[i]);
        printf("%d\n",a[n]);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_41181881/article/details/81265324