zoukankan      html  css  js  c++  java
  • 单调栈与单调队列

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

      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
  • 相关阅读:
    匿名函数
    Ajax
    Mysql 数据库操作
    Linux下查看apache连接数
    c++ 当输入的数据不符合数据类型时,清理输入流
    c++ 将输入存储到数组,然后反转数组,最后输出
    c++ 递归求一个数的阶乘
    c++ 计算彩票中奖概率
    c++ 结构体,设置物品体积并输出物品属性
    c++ 输入10个数,显示它的平均分
  • 原文地址:https://www.cnblogs.com/monmonde/p/3932560.html
Copyright © 2011-2022 走看看