单调栈与单调队列

个人理解:单调队列就是单调栈的升级版。单调队列比单调栈只多了个队首元素出队。

  ACM-ICPC Asia Phuket Regional Programming Contest 2013  J:

  这道题感觉什么树套树啊,按权值建线段树啊都是可以得解的,但树套树太慢,按权值建线段树又太难写(我懒,所以不想写)。在看了别人的解题报告后,想了一下,得到了单调栈的做法。感觉真的很优美,因为在栈里的id和其对应的sum都是单调的。

  这种题目有两个最优条件,一是大小,二是位置。我觉得只有后加入的满足位置更优时,才能用这种单调栈的做法。比如,如果这道题求的是最大子序列,那就不能用单调栈来做了。

 1 #include <cstdlib>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <iostream>
 5 #define FOR(i,l,r) for (int i=(l);i<=(r);i++)
 6 using namespace std;
 7 const int maxn=500000+1;
 8 typedef long long LL;
 9 
10 int n,x;
11 LL sum[maxn];
12 int sta[maxn]; int pos;
13 int ef(LL d)
14 {
15     int l=1,r=pos,mid;
16     while (l<=r)
17     {
18         mid=l+r>>1;
19         if (sum[sta[mid]]<=d) l=mid+1;
20         else r=mid-1;
21     }
22     return r;
23 }
24 int main(){
25     for (int T;scanf("%d",&T)!=EOF;)
26         for (int p,ans;T--;)
27         {
28             scanf("%d%d",&n,&x);
29             FOR (i,1,n) scanf("%d",&p),sum[i]=sum[i-1]+p;
30             ans=n+1; sta[pos=1]=0;
31             FOR (i,1,n)
32             {
33                 p=ef(sum[i]-x);
34                 if (p) ans=min(ans,i-sta[p]);
35                 while (pos&&sum[sta[pos]]>=sum[i]) pos--;
36                 sta[++pos]=i;
37             }
38             printf("%d
",ans==n+1?-1:ans);
39         }
40     return 0;
41 }
Minimal Subarray Length
原文地址:https://www.cnblogs.com/monmonde/p/3932560.html