【单调队列】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 }

 

posted @ 2016-11-14 23:51  iiyiyi  阅读(399)  评论(0编辑  收藏  举报