Sound 静音问题

题目描述

数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的时间。

很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段。为了避免分成过多或者过少的非静音段,静音通常是这样定义的:m个采样的序列,该序列中采样的最大值和最小值之差不超过一个特定的阈值c。

请你写一个程序,检测n个采样中的静音。

输入格式

第一行有三个整数n,m,c( 1<= n<=1000000,1<=m<=10000, 0<=c<=10000),分别表示总的采样数、静音的长度和静音中允许的最大噪音程度。

第2行n个整数ai (0 <= ai <= 1,000,000),表示声音的每个采样值,每两个整数之间用空格隔开。

输出格式

列出了所有静音的起始位置i(i满足max(a[i, . . . , i+m−1]) − min(a[i, . . . , i+m−1]) <= c),每行表示一段静音的起始位置,按照出现的先后顺序输出。如果没有静音则输出NONE。

输入输出样例

输入 #1复制
7 2 0
0 1 1 2 3 2 2
输出 #1复制
2
6


#include<bits/stdc++.h>
#define N 1001000
using namespace std;

void read(int &x)
{
    x=0;
    char c=getchar();
    while(c<'0' or c>'9') c=getchar();
    while(c>='0' and c<='9') x=x*10+c-'0',c=getchar();
}

class SegmengTree
{
    private:
        struct node
        {
            int l,r;
            int s1,s2,a;
        }tree[N<<2];
        #define ls index<<1
        #define rs index<<1|1

        #define L tree[index].l
        #define R tree[index].r
        #define S1 tree[index].s1
        #define S2 tree[index].s2
        #define A tree[index].a

        #define lL tree[ls].l
        #define lR tree[ls].r
        #define lS1 tree[ls].s1
        #define lS2 tree[ls].s2
        #define lA tree[ls].a

        #define rL tree[rs].l
        #define rR tree[rs].r
        #define rS1 tree[rs].s1
        #define rS2 tree[rs].s2
        #define rA tree[rs].a
    public:
        void Update(int index){
            S1=max(lS1,rS1);
            S2=min(lS2,rS2);
        }
        void BuildTree(int l,int r,int index){
            L=l,R=r,A=S1=S2=0;
            if (l==r){
                int x;
                read(x);
                S1=S2=x;
                return;
            }
            int mid=(l+r)>>1;
            BuildTree(l,mid,ls);
            BuildTree(mid+1,r,rs);
            Update(index);
        }
        int QueryMax(int l,int r,int index)
        {
            if (l>R or L>r) return -1;
            if (l<=L and R<=r) return S1;
            return max(QueryMax(l,r,ls),QueryMax(l,r,rs));
        }
        int QueryMin(int l,int r,int index)
        {
            if (l>R or L>r) return 1000000000;
            if (l<=L and R<=r) return S2;
            return min(QueryMin(l,r,ls),QueryMin(l,r,rs));
        }
}T;

int n,m,c;
void Input(){
    scanf("%d%d%d",&n,&m,&c);
    T.BuildTree(1,n,1);
}

void Solve(){
    bool flag=0;
    for(int i=1;i+m-1<=n;i++){
        int Min=T.QueryMin(i,i+m-1,1),Max=T.QueryMax(i,i+m-1,1);
        if (Max-Min<=c){
            printf("%d\n",i);
            flag=1;
        }
    }
    if (!flag){
        puts("NONE\n");
    }
}

main()
{
    Input();
    Solve();
}

 

转载于:https://www.cnblogs.com/hrj1/p/11206093.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值