题目描述 数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的时间。
很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段。为了避免分成过多或者过少的非静音段,静音通常是这样定义的: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(); }