zoukankan      html  css  js  c++  java
  • Codeforecs 69E. Subsegments STL/线段树

    E. Subsegments
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Programmer Sasha has recently begun to study data structures. His coach Stas told him to solve the problem of finding a minimum on the segment of the array in , which Sasha coped with. For Sasha not to think that he had learned all, Stas gave him a new task. For each segment of the fixed length Sasha must find the maximum element of those that occur on the given segment exactly once. Help Sasha solve this problem.

    Input

    The first line contains two positive integers n and k (1 ≤ n ≤ 105, 1 ≤ k ≤ n) — the number of array elements and the length of the segment.

    Then follow n lines: the i-th one contains a single number ai ( - 109 ≤ ai ≤ 109).

    Output

    Print nk + 1 numbers, one per line: on the i-th line print of the maximum number of those numbers from the subarray ai ai + 1 … ai + k - 1that occur in this subarray exactly 1 time. If there are no such numbers in this subarray, print "Nothing".

    Sample test(s)
    input
    5 3
    1
    2
    2
    3
    3
    
    output
    1
    3
    2
    
    input
    6 4
    3
    3
    3
    4
    4
    2
    
    output
    4
    Nothing
    3
    

    ----------------------------

    To solve this problem you have to do a "move" subsegment and know :

     1. The set B of numbers, meeting once, with the function of extracting the maximum for O (logN)

    2.The set of numbers appearing on this subsegments with keeping the number of times,that this number is found on this subsegments, with function of verifying how many times the number in this subsegments for O (logN).

     

    While moving a segment from (a[i] .. a[i + k - 1]) for 1 item left (a[I + 1] .. a[I + k]) you have to:

    1) Check whether a[i] with a[I + k]. If yes, then there is no need to modify the set, otherwise proceed to item 2 and 3.

    2) Check how many times we have a[i] in the set A: if 2, then add a[i] to B, if 1, then remove it from  A and B. Do not forget to reduce the corresponding number of occurrences of a[i] in the current segment 1.

    3) Check, how many times we have a[I + k] in the set A: if 0, then add a[i] in the B and A, if 1, then remove it from B. Do not forget to increase the corresponding number of occurrences of a[i] the current interval to 1.

     

    After that, if the set is not empty, we should take peak from it.

     

    So the asymptotics of this process will be O(NlogN).

     

    As such data structures  set / map(for those who use C + +) and the Cartesian tree are suitable.

    ----------------------------------------

    写的有点挫。。。

    #include <iostream>
    #include <map>
    
    using namespace std;
    
    map<int,int>mp;
    map<int,int>::iterator it;
    map<int,int>co;
    int n,k;
    int a[111111];
    
    int main()
    {
        cin>>n>>k;
        for (int i=1; i<=n; i++) cin>>a[i];
        for (int i=1; i<=k; i++)
        {
            mp[a[i]]++;
            if (mp[a[i]]==1)
            {
                co.insert(pair<int,int>(a[i],1));
            }
            else
            {
                if (co.find(a[i])!=co.end()) co.erase(a[i]);
            }
        }
        it=co.end();
        if (it!=co.begin()) it--;
        if (co.empty()) cout<<"Nothing"<<endl;
        else cout<<it->first<<endl;
        for (int i=k+1; i<=n; i++)
        {
            mp[a[i]]++;
            mp[a[i-k]]--;
            if (mp[a[i]]==1)
            {
                co.insert(pair<int,int>(a[i],1));
            }
            else
            {
                if (co.find(a[i])!=co.end()) co.erase(a[i]);
            }
            if (mp[a[i-k]]==1)
            {
                co.insert(pair<int,int>(a[i-k],1));
            }
            else
            {
                if (co.find(a[i-k])!=co.end()) co.erase(a[i-k]);
            }
            it=co.end();
            if (it!=co.begin()) it--;
            if (co.empty()) cout<<"Nothing"<<endl;
            else cout<<it->first<<endl;
        }
        return 0;
    }
    








  • 相关阅读:
    bzoj 1015: [JSOI2008]星球大战starwar【并查集】
    bzoj 1026: [SCOI2009]windy数【数位dp】
    bzoj 3231: [Sdoi2008]递归数列【矩阵乘法】
    bzoj 4198: [Noi2015]荷马史诗【哈夫曼树+贪心】
    bzoj 1093: [ZJOI2007]最大半连通子图【tarjan+拓扑排序+dp】
    bzoj 3209: 花神的数论题【数位dp】
    bzoj [JSOI2010]Group 部落划分 Group【二分+并查集】
    bzoj 1087: [SCOI2005]互不侵犯King【状压dp】
    bzoj 2730: [HNOI2012]矿场搭建【tarjan】
    bzoj 1878: [SDOI2009]HH的项链【树状数组】
  • 原文地址:https://www.cnblogs.com/cyendra/p/3038417.html
Copyright © 2011-2022 走看看