• 杭电2018暑假多校第一场 D Distinct Values hdu6301 贪心


    Distinct Values

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1411    Accepted Submission(s): 439


    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 (li<jr), aiajholds.
    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 (1n,m105) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1lirin).

    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
     
    Source
     
    题意:题目要求的是构造一个数组在区间内各点的值不相同,且构造的数组字典序要最小

    分析:由题意可以得到,终点相同的区间他们的起点可以简化成几个区间内最小的起点

    而要使值都不相同,我们首先要知道的是每个点的起始点,然后看这个点的区间内已经填了哪些值,我们再填除了这些值外最小的点,每个点的起始点就是其所在区间的起始点

    求出每个点的起始点后,我们只需要用个值记录下这个区间前面的点出现过的值

    在这里我们用set存每出现过的值,首先把所有可能的值加入set(用set的好处是他自己排序,第一个为最小的),然后在第一个区间一个个依次加入,每加入一个我们删去一个

    接下来的区间用记录的值与区间的起始点比较,如果小于点的起始点的值,证明前面的点没出现过再加入我们的集合,然后取set的第一个值就行了

    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #define debug(a) cout << #a << " " << a << endl
    using namespace std;
    const int maxn = 1e5+10;
    const int mod = 1e9 + 7;
    typedef long long ll;
    ll pre[maxn], ret[maxn];
    int main() {
        std::ios::sync_with_stdio(false);
        ll T, n, m;
        cin >> T;
        while( T -- ) {
            cin >> n >> m;
            for( ll i = 1; i <= n; i ++ ) {
                pre[i] = i;
            }
            for( ll i = 0, le, ri; i < m; i ++ ) {
                cin >> le >> ri;
                pre[ri] = min( pre[ri], le );   //相同终点的区间起点取小的
            }
            for( ll i = n-1; i >= 1; i -- ) {
                pre[i] = min( pre[i], pre[i+1] );//将处在区间内的点的起点定义为区间的起点
                //debug(pre[i]);
            }
            ll p1 = 1;  //代表数字用到哪一个点的,前面填充好,后面通过p1对应到前面的点
            set<ll> s;
            for( ll i = 1; i <= n; i ++ ) {
                s.insert(i);
            }
            for( ll i = 1; i <= n; i ++ ) {
                //debug(i);
                while( p1 < pre[i] ) {  //p1根据区间不同不断更新,当小于i点的区间起点时p1进行更新
                    s.insert(ret[p1]);
                    // debug(ret[p1]);
                    p1 ++;
                }
                ret[i] = *s.begin();
                debug(ret[i]);
                s.erase(ret[i]);
            }
            for( ll i = 1; i <= n; i ++ ) {
                if( i != n ) {
                    cout << ret[i] << " ";
                } else {
                    cout << ret[i] << endl;
                }
            }
        }
        return 0;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    ceph之image(转)
    CEPH集群RBD快照创建、恢复、删除、克隆(转)
    java操作ceph之rbd基本操作
    Kubernetes (1.6) 中的存储类及其动态供给
    Linux 网络编程详解九
    Linux 网络编程详解八
    Linux 网络编程详解七(并发僵尸进程处理)
    Linux 网络编程详解六(多进程服务器僵尸进程解决方案)
    Linux 网络编程详解五(TCP/IP协议粘包解决方案二)
    C语言 memset函数盲点
  • 原文地址:https://www.cnblogs.com/l609929321/p/9358636.html
Copyright © 2020-2023  润新知