Codeforecs H. Subsegments
Posted zhanhonhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforecs H. Subsegments相关的知识,希望对你有一定的参考价值。
思路:
刚开始:
利用map来统计长度为k的一段上的数字及其出现次数,不断更新区段位置,减去退出区段的数字的出现次数,加上新出现的数字及其出现次数,每次都从后向前遍历一遍map,如果遇到一个数且出现次数为1,那么他就是当前区段上的最大数(因为map中已排好序),break,当前循环结束。这种方法果然想的太简单,超时
然后:问题出在哪?前面的不断更新和统计都是在log n时间完成的,应该没有问题。如果出现一种情况,在求当前区间最大值的时候,都是出现不止一次的数,就意味着要遍历整个map。
结果:利用set方便求最值,set自身也是一种树形结构,操作在log n内可以完成。因为set的元素不重样,我们只需将map中出现次数为1的数丢进set,每次更新区段时,先看退出的数出现次数是否减少到一,是则丢入set,不是看是不是在set中出现,如果出现就set中erase它,因为它的出现次数不为1,不在比较范围内。先加入元素看出现次数是否唯一,唯一加入set,不唯一看set中是否有,有就删除。再从set中选最大值,即最后一个(set已经排好序),一轮循环结束。
知识点:
set的insert,empty,end(),rend(),rbegin()(反向迭代器,十分方便)
map的[]访问方式
下面是代码:
1 #include <iostream> 2 #include <map> 3 #include <set> 4 #include <climits> 5 #define max_n 100005 6 using namespace std; 7 int a[max_n]; 8 map<int,int> num; 9 set<int> sets; 10 int n; 11 int k; 12 int main() 13 14 cin >> n >> k; 15 for(int i = 0;i<n;i++) 16 17 cin >> a[i]; 18 19 for(int i = 0;i<k;i++) 20 21 num[a[i]]++; 22 if(num[a[i]]==1) 23 24 sets.insert(a[i]); 25 26 else 27 28 if(sets.find(a[i])!=sets.end()) 29 30 sets.erase(a[i]); 31 32 33 34 if(sets.empty()) 35 36 cout << "Nothing" << endl; 37 38 else 39 40 auto i = sets.rbegin(); 41 cout << *i << endl; 42 43 int f = 0; 44 int b = k; 45 for(;b<n;f++,b++) 46 47 num[a[f]]--; 48 num[a[b]]++; 49 if(num[a[f]]==1) 50 51 sets.insert(a[f]); 52 53 else 54 55 if(sets.find(a[f])!=sets.end()) 56 57 sets.erase(a[f]); 58 59 60 if(num[a[b]]==1) 61 62 sets.insert(a[b]); 63 64 else 65 66 if(sets.find(a[b])!=sets.end()) 67 68 sets.erase(a[b]); 69 70 71 if(sets.empty()) 72 73 cout << "Nothing" << endl; 74 75 else 76 77 auto i = sets.rbegin(); 78 cout << *i << endl; 79 80 /*for(auto i = num.rbegin();i!=num.rend();i++) 81 82 cout << i->first << "-" << i->second << endl; 83 */ 84 85
以上是关于Codeforecs H. Subsegments的主要内容,如果未能解决你的问题,请参考以下文章