[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\n");
25                 else{
26                     printf("%d\n",*(--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\n");
46             else{
47                  printf("%d\n",*(--s.end()));
48             }
49         }
50     }
51 }
52 /***
53 先把前k个数排序并找出只出现一次的那些数,就可以的到第一次询问的答案,
54 然后从k+1开始,每加入一个数就删去上一个区间的第一个数,并看删去的那个数的个数
55 是否为1,若为1则加入可行集合,否则就看它是否在可行集合中(因为刚才删了一次,若它在可行集合中那么它的数量就为0了,要把它给删了)
56 若在就删了它。再看新加进来的那个数的个数是否为1,如果是就加入可行集合,否则就看它是否在可行集合中(如果它在可行集合中,那么它现在的数量为1,现在又加了一次它,它的个数就大于1,不符合条件了),若在就把它给删了
57 每次输出可行集合中最大的那个数
58 ***/

 

全部评论

相关推荐

黑皮白袜臭脚体育生:简历统一按使用了什么技术实现了什么功能解决了什么问题或提升了什么性能指标来写会更好另外宣传下自己的开源仿b站微服务项目,GitHub已经410star,牛客上有完整文档教程,如果觉得有帮助的话可以点个小星星,蟹蟹
点赞 评论 收藏
分享
昨天 00:16
已编辑
湖北大学 Java
Java抽象带篮子:java简历怎么写可以看看我发的帖子,很详细的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务