zoukankan      html  css  js  c++  java
  • Codeforces 547B Mike and Feet(单调栈)

    题目链接:http://codeforces.com/problemset/problem/547/B

    题目大意:
    有一个长度为n的序列,序列有长度为1...n的连续子序列,一个连续子序列里面最小的值称作这个子序列的子序列的strength,
    要求出每种长度的连续子序列的最大的strength。
    解题思路:
    可以用栈求出每个点的l[i],表示值小于当前位置并且在左侧的最接近这个点的位置。
    同理可以求出r[i],表示值小于当前位置并且在右侧侧的最接近这个点的位置。
    求l[i]过程如下:
    stack s // initially empty
    for i = 1 to n
    while s is not empty and a[s.top()] >= a[i]
    do s.pop()
    if s is empty
    then l[i] = 0
    otherwise
    l[i] = s.top()
    s.push(i)
    接下来,我们遍历每个位置i,令len=r[i]-l[i]-1,则ans[len]=min(a[i],ans[len])
    可以理解为在r[i]-1~l[i]+1这块长度为len的区间上,最小的就是a[i],所以ans[len]与a[i]比较。
    最后还要从len=n-1~1遍历,令ans[len]=max(ans[len],a[len+1])。
    为什么要这么做?
    因为不这样做,如1 2 3 2 1这组样例,只能求出ans[1]、ans[3]、ans[5],像ans[2]、ans[4]都是空的。
    这样做的意义就是如果ans[len]为空,则把ans[len+1]的值给它。
    为什么是ans[len+1]的值,首先ans[len]>=ans[len+1],假设我们有一个长度为len+1的只有x~y的区间,min=2,则a[len+1]=2,
    假设a[len]会大于a[len+1],那么必定存在x+1~y或者x~y-1的区间且min>2,但是如果ans[len-1]为空则说明没有这样的区间
    所以取ans[len]=ans[len+1]。

    代码

     1 #include<bits/stdc++.h>
     2 #define lc(a) (a<<1)
     3 #define rc(a) (a<<1|1)
     4 #define MID(a,b) ((a+b)>>1)
     5 #define fin(name)  freopen(name,"r",stdin)
     6 #define fout(name) freopen(name,"w",stdout)
     7 #define clr(arr,val) memset(arr,val,sizeof(arr))
     8 #define _for(i,start,end) for(int i=start;i<=end;i++)
     9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    10 using namespace std;
    11 typedef long long LL;
    12 const int N=2e5+5;
    13 const int INF=0x3f3f3f3f;
    14 const double eps=1e-10;
    15 
    16 int l[N],r[N],a[N],ans[N];
    17 stack<int>sk;
    18 
    19 int main(){
    20     FAST_IO;
    21     int n;
    22     cin>>n;
    23     for(int i=1;i<=n;i++){
    24         cin>>a[i];
    25     }
    26     for(int i=1;i<=n;i++){
    27         while(!sk.empty()&&a[sk.top()]>=a[i]) 
    28             sk.pop();
    29         if(!sk.empty())
    30             l[i]=sk.top();
    31         else
    32             l[i]=0;
    33         sk.push(i);
    34     }
    35     while(!sk.empty()) sk.pop();
    36     for(int i=n;i>=1;i--){
    37         while(!sk.empty()&&a[sk.top()]>=a[i])
    38             sk.pop();
    39         if(!sk.empty())
    40             r[i]=sk.top();
    41         else
    42             r[i]=n+1;
    43         sk.push(i);
    44     }
    45     for(int i=1;i<=n;i++){
    46         int len=r[i]-l[i]-1;
    47         ans[len]=max(a[i],ans[len]);
    48     }
    49     for(int i=n-1;i>=1;i--){
    50         ans[i]=max(ans[i],ans[i+1]);
    51     }
    52     for(int i=1;i<=n;i++){
    53         cout<<ans[i]<<" ";
    54     }
    55     cout<<endl;
    56     return 0;
    57 }
  • 相关阅读:
    上周热点回顾(2.12-2.18)团队
    上周热点回顾(2.5-2.11)团队
    上周热点回顾(1.29-2.4)团队
    云计算之路-阿里云上:部分服务器未及时续费造成docker swarm集群故障团队
    Git学习系列之Windows上安装Git之后的一些配置(图文详解)
    Git学习系列之Git 的缺点有哪些?
    Git学习系列之Git的功能特性(从一般开发者的角度和主开发者的角度来剖析)
    Git学习系列之经典的Git开发过程
    Git学习系列之Windows上安装Git详细步骤(图文详解)
    Git学习系列之集中式版本控制系统vs分布式版本控制系统
  • 原文地址:https://www.cnblogs.com/fu3638/p/9892324.html
Copyright © 2011-2022 走看看