【BZOJ1342】Sound静音问题
1342: [Baltic2007]Sound静音问题
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 858 Solved: 383
[Submit][Status][Discuss]
Description
静音问题 数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的时间。 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段。为了避免分成过多或者过少的非静音段,静音通常是这样定义的:m个采样的序列,该序列中采样的最大值和最小值之差不超过一个特定的阈值c。 请你写一个程序,检测n个采样中的静音。
Input
第一行有三个整数n,m,c( 1<= n<=1000000,1<=m<=10000, 0<=c<=10000),分别表示总的采样数、静音的长度和静音中允许的最大噪音程度。第2行n个整数ai (0 <= ai <= 1,000,000),表示声音的每个采样值,每两个整数之间用空格隔开。
Output
列出了所有静音的起始位置i(i满足max(a[i, . . . , i+m−1]) − min(a[i, . . . , i+m−1]) <= c),每行表示一段静音的起始位置,按照出现的先后顺序输出。如果没有静音则输出NONE。
Sample Input
7 2 0
0 1 1 2 3 2 2
0 1 1 2 3 2 2
Sample Output
2
6
6
HINT
Source
sol:
单调队列 复杂度$O(n)$
板子题
/*In Search Of Life*/ #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<iomanip> #include<stack> #include<map> #include<set> #include<cmath> #define debug(x) cerr<<#x<<"="<<x<<endl #define INF 0x7f7f7f7f #define llINF 0x7fffffffffffll using namespace std; typedef pair<int,int> pii; typedef long long ll; inline int init() { int now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } inline long long llinit() { long long now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } int qa[1000005],qb[1000005],a[1000005]; int head=1,tail=0; int maxx[1000005],minx[1000005]; int main() { freopen("sound.in","r",stdin); freopen("sound.out","w",stdout); bool f=false; int n,m,c; n=init();m=init();c=init(); for(int i=1;i<=n;i++)a[i]=init(); for(int i=1;i<=n;i++) { while(tail>=head&&a[qa[tail]]>a[i]) { --tail; } qa[++tail]=i; while(head<=tail&&qa[tail]-qa[head]>=m) { ++head; } minx[i]=a[qa[head]]; } head=1,tail=0; for(int i=1;i<=n;i++) { while(tail>=head&&a[qb[tail]]<a[i]) { --tail; } qb[++tail]=i; while(head<=tail&&qb[tail]-qb[head]>=m) { ++head; } maxx[i]=a[qb[head]]; if(maxx[i]-minx[i]<=c&&i>=m) { printf("%d\n",i-m+1); f=1; } } if(!f)puts("NONE"); return 0; }