bzoj1342[Baltic2007]Sound静音问题*
题意:
给出一个n个数的序列,问有多少个长度为m的区间满足该区间的最大值与最小值的差≤一个定值。n≤1000000。
题解:
两个单调队列,一个维护区间最大值,一个维护区间最小值。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 10010 7 using namespace std; 8 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 13 return f*x; 14 } 15 struct nd{int v,pos;}; 16 struct dddl{ 17 deque<nd>mx; deque<nd>mn; 18 void insert(int x,int y){ 19 while(!mx.empty()&&x>=mx.back().v)mx.pop_back(); mx.push_back((nd){x,y}); 20 while(!mn.empty()&&x<=mn.back().v)mn.pop_back(); mn.push_back((nd){x,y}); 21 } 22 void erase(int x){ 23 while(!mx.empty()&&x>=mx.front().pos)mx.pop_front(); 24 while(!mn.empty()&&x>=mn.front().pos)mn.pop_front(); 25 } 26 }dddl; 27 int n,m,c,a[maxn]; bool f; 28 int main(){ 29 n=read(); m=read(); c=read(); inc(i,1,m){int x=read(); dddl.insert(x,i);} f=0; 30 if(dddl.mx.front().v-dddl.mn.front().v<=c)printf("%d\n",1),f=1; 31 inc(i,m+1,n){ 32 dddl.erase(i-m); int x=read(); dddl.insert(x,i); 33 if(dddl.mx.front().v-dddl.mn.front().v<=c)printf("%d\n",i-m+1),f=1; 34 } 35 if(!f)puts("NONE"); return 0; 36 }
20161111