zoukankan      html  css  js  c++  java
  • 杭电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;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    Java 9 揭秘(9. 打破模块封装)
    Java 9 揭秘(8. JDK 9重大改变)
    好书分享 ——《深度工作》
    Java 9 揭秘(7. 创建自定义运行时映像)
    Java 9 揭秘(6. 封装模块)
    如何更好地管理你的精力,时间和专注力实现最佳表现
    这是您一直期待的所有iOS 11功能的屏幕截图
    我为什么不敢也不想写自己的经验和想法?
    无聊? 现在你知道为什么了!
    Java 9 揭秘(5. 实现服务)
  • 原文地址:https://www.cnblogs.com/l609929321/p/9358636.html
Copyright © 2011-2022 走看看