• 【Luogu】P2422良好的感觉(单调栈)


      题目链接

      写代码能力需要极大提升。我在五分钟之内想到了单调栈,然后花了一个小时的时间去看我单调队列为啥写错了……

      首先这题需要转换自己的思维。枚举所有“最小点”,然后看它往左往右最大能扩展多少。

      维护一个单调递增的序列,弹栈时就会是这种情况:

      设被弹出去的元素是s,那它为什么会被弹出去呢?因为它比当前元素大。

      比当前元素大说明了什么呢?说明如果有一个区间以它为最小值,那这个区间向右扩展的极限就在当前元素前面。因为区间不能继续向右扩展,一扩展,区间就包含当前元素了,那元素s就不是最小值了,而我们这个区间又是以s为最小值的区间……

      所以我们分析出了区间的右端点。区间的左端点在栈顶的下面一个元素停住。推理同上。

      于是一个区间枚举成功。可以把这个区间的价值和当前答案比对并更新答案。

      代码如下。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    long long ans;
    long long sum[1000010];
    long long que[1000010];
    int d[1000010],t;
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%lld",&que[i]);
            sum[i]=sum[i-1]+que[i];
            while(t&&que[d[t]]>=que[i]){
                ans=max(ans,que[d[t]]*(sum[i-1]-sum[d[t-1]]));
                t--;
            }
            d[++t]=i;
        }
        while(t){
            ans=max(ans,que[d[t]]*(sum[n]-sum[d[t-1]]));
            t--;
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Windows 7 任务计划程序
    '7z' 不是内部或外部命令,也不是可运行的程序
    [转]国外人气最旺的软件测试网站
    AutoIT查找文件内容并修改保存
    BUG 太少
    excel表格数据导入sqlserver数据库
    RoR常见问题
    [转]漫画:程序员的一生
    [转]RubyInstaller: Getting Started with Rails and SQLite3
    [转]C#多线程学习(一) 多线程的相关概念
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7526679.html
Copyright © 2020-2023  润新知