zoukankan      html  css  js  c++  java
  • 单调栈

    描述:求一个数组的某一个数,向左右两边延申的最大区间,比如1276453.对于4可以向左延申到7,向右延申到5,也就是4在这个区间内是最小值。

    适用:对于一个数组,如果对于全部区间去求解,需要n*(n-1)/2个区间,所以问题的复杂度至少是N的平方,如果换一个角度,所有的区间都是以某一个数字作为最小值的,所以只要求出一个数代表一个区间,就可以转换为O(n)的复杂度。

    #include<stdio.h>
    #include<math.h>
    #include<iostream>
    #include<stack>
    using namespace std;
    const int maxn=100010;
    long long a[100010];
    int l[100010],r[100010],n,ansl,ansr,top;
    
    long long  sum[100010]={0},ans=-1;
    
    int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
    scanf("%lld",&a[i]);
    sum[i]=sum[i-1]+a[i];
    l[i]=r[i]=i;
    } 
    a[0]=a[n+1]=-1;
    
    stack<int>s;   
    for(i=1;i<=n+1;i++){
    while(!s.empty()&&a[i]<=a[s.top()]  ){//a[i]<栈顶,出栈 
     r[s.top()] =i-1;//找出栈顶元素的下标右端点 
     s.pop();
    }  
    if(!s.empty())l[i]=s.top()+1;  
    else l[i]=1;
       s.push(i);
    
    } 
    
    long long tmp;
    for(i=1;i<=n;i++){
    
    tmp=(sum[r[i]]-sum[l[i]-1])*a[i];
    if(tmp>=ans){
    ans=tmp;
    ansl=l[i];
    ansr=r[i];
    } 
    }
    printf("%lld
    ", ans);
      printf("%d %d
    ", ansl, ansr);
    return 0;
    }
  • 相关阅读:
    docker进入mysql命令窗口
    dyoYQoyfRb
    2018icpc 徐州h题
    求逆元
    取模的n种情况
    Eratos筛法(筛选素数)
    扩展欧几里得
    函数库里有三角函数 和反三角函数
    HDU2795线段树入门 简单查询和修改
    快速排序 分析
  • 原文地址:https://www.cnblogs.com/mdumpling/p/9501271.html
Copyright © 2011-2022 走看看