【单调队列】BZOJ1342-[Baltic2007]Sound静音问题
【题目大意】
给出一个n个数的序列,以哪位位置为开头的长度为m的区间满足该区间的最大值与最小值的差≤一个定值。
【思路】
单调队列……说一下单调队列比较方便的操作。
把第一个先丢进去,开始条件为head=tail=1。就OK了。我以前总是喜欢左闭右开,还是都闭合好了不容易写错QAQ
所以……越刷越水,去睡觉!
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=1000000+50; 4 int maxque[MAXN],minque[MAXN]; 5 int n,m,c,v[MAXN],ans[MAXN]; 6 int l1,r1,l2,r2; 7 8 void solve() 9 { 10 scanf("%d%d%d",&n,&m,&c); 11 l1=l2=1,r1=r2=1; 12 scanf("%d",&v[1]); 13 maxque[1]=minque[1]=1; 14 ans[0]=0; 15 if (m==1) ans[0]++,ans[ans[0]]=1; 16 for (int i=2;i<=n;i++) 17 { 18 scanf("%d",&v[i]); 19 while (maxque[l1]<=i-m && l1<=r1) l1++; 20 while (v[maxque[r1]]<=v[i] && l1<=r1) r1--; 21 maxque[++r1]=i; 22 23 while (minque[l2]<=i-m && l2<=r2) l2++; 24 while (v[minque[r2]]>=v[i] && l2<=r2) r2--; 25 minque[++r2]=i; 26 27 if (i>=m && v[maxque[l1]]-v[minque[l2]]<=c) ans[++ans[0]]=i-m+1; 28 } 29 30 if (ans[0]==0) puts("NONE"); 31 else for (int i=1;i<=ans[0];i++) printf("%d\n",ans[i]); 32 } 33 34 int main() 35 { 36 solve(); 37 return 0; 38 }