• [STL] Codeforces 69E Subsegments


    Subsegments
    time limit per test
    1 second
    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".

    Examples
    input
    Copy
    5 3
    1
    2
    2
    3
    3
    output
    Copy
    1
    3
    2
    input
    Copy
    6 4
    3
    3
    3
    4
    4
    2
    output
    s
    Copy
    4
    Nothing
    3

    题意:给一个长度为n的数字,输出i从1到n-k-1,i到i+k-1这个区间内若存在只出现一次的区间最大值则输出这个值,否则输出Nothing

    思路:先把前k个数排序并找出只出现一次的那些数,就可以的到第一次询问的答案,
    然后从k+1开始,每加入一个数就删去上一个区间的第一个数,并看删去的那个数的个数
    是否为1,若为1则加入可行集合,否则就看它是否在可行集合中(因为刚才删了一次,若它在可行集合中那么它的数量就为0了,要把它给删了)
    若在就删了它。再看新加进来的那个数的个数是否为1,如果是就加入可行集合,否则就看它是否在可行集合中(如果它在可行集合中,那么它现在的数量为1,现在又加了一次它,它的个数就大于1,不符合条件了),若在就把它给删了
    每次输出可行集合中最大的那个数

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int amn=1e5+5;
     4 int a[amn];
     5 map<int,int> mp;    ///个数统计,a[i]最大是1e9,故用map统计
     6 set<int> s; ///可行集合
     7 int main(){
     8     int n,k;
     9     ios::sync_with_stdio(0);
    10     cin>>n>>k;
    11     for(int i=1;i<=n;i++){
    12         cin>>a[i];
    13         if(i<=k){
    14             mp[a[i]]++;
    15             if(mp[a[i]]==1){
    16                 s.insert(a[i]);
    17             }
    18             else{
    19                 if(s.find(a[i])!=s.end()){
    20                     s.erase(a[i]);
    21                 }
    22             }
    23             if(i==k){
    24                 if(s.empty())printf("Nothing
    ");
    25                 else{
    26                     printf("%d
    ",*(--s.end()));    ///set升序排序,输出最后一个
    27                 }
    28             }
    29         }
    30         else{
    31             mp[a[i]]++;
    32             mp[a[i-k]]--;
    33             if(mp[a[i-k]]==1)s.insert(a[i-k]);
    34             else{                               ///可能为0了,如果这个数在可行集合中就要把它删掉
    35                 if(s.find(a[i-k])!=s.end()){
    36                     s.erase(a[i-k]);
    37                 }
    38             }
    39             if(mp[a[i]]==1)s.insert(a[i]);
    40             else{
    41                 if(s.find(a[i])!=s.end()){
    42                     s.erase(a[i]);
    43                 }
    44             }
    45             if(s.empty())printf("Nothing
    ");
    46             else{
    47                  printf("%d
    ",*(--s.end()));
    48             }
    49         }
    50     }
    51 }
    52 /***
    53 先把前k个数排序并找出只出现一次的那些数,就可以的到第一次询问的答案,
    54 然后从k+1开始,每加入一个数就删去上一个区间的第一个数,并看删去的那个数的个数
    55 是否为1,若为1则加入可行集合,否则就看它是否在可行集合中(因为刚才删了一次,若它在可行集合中那么它的数量就为0了,要把它给删了)
    56 若在就删了它。再看新加进来的那个数的个数是否为1,如果是就加入可行集合,否则就看它是否在可行集合中(如果它在可行集合中,那么它现在的数量为1,现在又加了一次它,它的个数就大于1,不符合条件了),若在就把它给删了
    57 每次输出可行集合中最大的那个数
    58 ***/
  • 相关阅读:
    ansible管理windows实践
    SQL server 备份/恢复/压缩 进度查询
    什么是容器
    pycharm 快捷键
    SUSE Linux--zypper程序包管理(实战命令总结)
    源码编译安装
    CentOS-yum基本使用
    rpm管理
    btrfs的精简总结版
    btrfs的介绍与使用
  • 原文地址:https://www.cnblogs.com/Railgun000/p/11291012.html
Copyright © 2020-2023  润新知