BZOJ 1342 单调队列

1342: [Baltic2007]Sound静音问题

Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 960 Solved: 430
[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

Sample Output

2

6

HINT

Source

#include <cstdio>
#include <iostream>
#include <queue> 
using namespace std;
int n,m,c;
int s[1000005];
int l1,l2,r1,r2;
int id1[1000005];
int id2[1000005];
int x1[1000005];
int x2[1000005];
int main(){
    scanf("%d%d%d",&n,&m,&c);
    for(int i=1;i<=n;i++) scanf("%d",&s[i]);
    l1=l2=1;
    r1=r2=0;
    bool flag=1;
    for(int i=1;i<=n;i++){

        while(l1<=r1&&i-id1[l1]>=m) l1++;
        while(l2<=r2&&i-id2[l2]>=m) l2++;
        while(l1<=r1&&s[i]>=x1[r1]) r1--;
        while(l2<=r2&&s[i]<=x2[r2]) r2--;
        id1[++r1]=id2[++r2]=i;
        x1[r1]=x2[r2]=s[i];
    // if(i>=m&&x1[l1]-x2[l1]<=c) 
        if(i>=m)if(x1[l1]-x2[l2]<=c)
            printf("%d\n",i-m+1),flag=0;

    }
    if(flag) puts("NONE");
    return 0;
}

维护两个单调队列~~

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务