【尺取法】【Multiset】bzoj1342 [Baltic2007]Sound静音问题

O(n)地枚举所有长度为k的段,每次暴力转移。

转移的时候只是从最后插入一个数,从前面删去一个数。

计算的时候要取当前的max和min。

用multiset(∵元素是可重的)以上这些操作都是O(logn)的。

 1 #include<cstdio>
 2 #include<set>
 3 using namespace std;
 4 multiset<int>S;
 5 multiset<int>::iterator it;
 6 int n,m,limit; bool goal;
 7 int a[1000001];
 8 int main()
 9 {
10     scanf("%d%d%d",&n,&m,&limit);
11     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
12     for(int i=1;i<=m;i++) S.insert(a[i]);
13     it=S.end(); it--;
14     if((*it)-(*S.begin())<=limit) puts("1"),goal=1;
15     for(int i=2;i<=n-m+1;i++)
16       {
17           S.erase(S.find(a[i-1]));
18           S.insert(a[m+i-1]);
19           it=S.end(); it--;
20           if((*it)-(*S.begin())<=limit) printf("%d\n",i),goal=1;
21       }
22     if(!goal) puts("NONE");
23     return 0;
24 }
时间: 2024-08-05 16:16:38

【尺取法】【Multiset】bzoj1342 [Baltic2007]Sound静音问题的相关文章

[bzoj1342][Baltic2007]Sound静音问题_单调队列

Sound静音问题 bzoj-1342 Baltic-2007 题目大意:给定一个n个数的序列,求所有的长度为m的区间,使得区间内最大值减去最小值不超过阈值c. 注释:$1\le n \le 10^6$,$1\le m\le 10^4$. 想法:单调队列裸题. 定长区间最值问题显然可以用单调队列维护. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include &

BZOJ1342 [Baltic2007]Sound静音问题

越来越水了... 这道题是简单的单调队列,同时维护最大值和最小值即可. 另解:multiset大法求区间最大最小,但是复杂度会上升... 1 /************************************************************** 2 Problem: 1342 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:944 ms 7 Memory:12524 kb 8 ***************

1342: [Baltic2007]Sound静音问题

1342: [Baltic2007]Sound静音问题 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 710  Solved: 307[Submit][Status][Discuss] Description 静音问题 数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的时间. 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段.为了避免分成过多或者过少的非静音段,静音通常是这样定义的:m

BZOJ 1342 Baltic2007 Sound静音问题 单调队列

题目大意:给定一个长度为n的序列,求哪些长度为m的区间满足区间内最大值与最小值之差小于等于c 利用单调队列维护区间内的最大值和最小值- - 硬搞就可以了- - 刷刷水题真爽- - #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001 using namespace std; int n,m,c,a[M]; int q_ma

BZOJ_1342_[Baltic2007]Sound静音问题_单调队列

题意: 给出n个数,求∑[ max{a[i]~a[i+m-1]} - min{a[i]~a[i+m-1]} <= c ] 分析: 滑动窗口 我们维护两个单调队列,分别存最大,最小值 代码: #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define N

Sound静音问题

1342: [Baltic2007]Sound静音问题 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1183  Solved: 542[Submit][Status][Discuss] Description 数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的 时间. 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段.为了避免分成过多或者过少的非 静音段,静音通常是这样定义的:m个采

尺取法总结

最近在做尺取法,总结一下 尺取法,说白了就是一个st,ed:这两个左右端点(起点.终点)在运动,适用条件就是要求一段连续的区间, 并且st(左端点)++的时候,一个更优的ed一定要大于或者等于原来的ed 所以尺取法是一种高效的枚举区间的方法,一般用于求取有一定限制的区间个数或最短的区间等等. 而且经常与map.set.multiset等连用 这里推荐几道题: 1.poj3061 #include<stdio.h> #include<string.h> #include<alg

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi