2018 Multi-University Training Contest 1-1004-Distinct Values HDU 6301

2018 Multi-University Training Contest 1-1004-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 .

Outpu

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

杭电多校训练第一场1004

一开始我是不会的……听了dalao讲后琢磨了一天才勉强会……菜哭……

题的大意是:有一个n元素数组,给m个事实:从al到ar每个元素都不一样,求字典序最小的数组。


做法:贪心。

结果数组res。

开一个数组pre[i];记录第i个元素最多受限在pre[i];就是从 pre[i] 到 i 都不相同。

1:初始化:pre[i]=i;受限于他本身。

2:输入的时候pre[r]=min(pre[r],l);受限于左端,及l—r都不相同。至于还要和pre[r]比 ,是因为有可能多次修改,要取最小。

3:从后往前在过一遍,pra[i]=min(pra[i],pra[i+1]):保证最优。

开一个 set <int> unused; ,记录可以使用的数。

1:初始化:从1到n都能用。

2:添加:这里就要定义一个p:当p<pre[i];及小于受限位置的时候,p到pre[i]中的结果放入unused,p移到pre[i];

3:删除:每用一个删一个~。


然后就完了……完了……

写出来感觉自己好笨/(ㄒoㄒ)/~~

代码参上:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
int pra[1000005],res[1000005];

int main()
{
    cin>>T;
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n+1;i++)
            pra[i]=i;
        for(int i=0;i<m;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            pra[r]=min(pra[r],l);
        }
        for(int i=n;i>0;i--)
            pra[i]=min(pra[i],pra[i+1]);
        set <int> unused;
        for(int i=1;i<=n+1;i++)
            unused.insert(i);
        int p=1;
        for(int i=1;i<=n;i++)
        {
            while(p<pra[i])
            {
                unused.insert(res[p]);
                p++;
            }
            res[i]=*unused.begin();
            unused.erase(res[i]);

        }
        for(int i=1;i<n;i++)
            printf("%d ",res[i]);
        printf("%d\n",res[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xuanhuangwendao/article/details/81194074