Neat Tree

Neat Tree

https://ac.nowcoder.com/acm/problem/15815

单调栈

单调栈接触挺久了,一直没有仔细研究。
昨天模拟赛,一道单调栈没有看出来。
现在认真学学!

对于这道题,因为它是连续子序列
所以我们可以统计每一个值的贡献
即,(作为最大值的次数-作为最小值的次数)*高度

如何求作为最大值的次数?
我们可以求解,向左走第一个比他大的索引,向右走第一个比他大的索引
那么,在这个区间内。他就是最大值!
利用单调栈可以很容易地统计出来!

然后我们可以用同样的方法统计出最小值的次数

但是哇,我们这样有一个bug
就是,这个区间内有重复的数,我们统计时可能会有区间被重复选取!
那么该怎么办呢?

学到了!
我们可以在单调栈判断时,对于左边我们取等,对于右边我们不取等!
真的巧妙!

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int max_n = 1e6+100;
const int inf = 1e9;
int h[max_n],lft[max_n],rgt[max_n];
int n;

int main(){
    ios::sync_with_stdio(0);
    while (cin>>n){
        for (int i=1;i<=n;++i)cin>>h[i];
        vector<int> stack;
        stack.push_back(0);
        h[n+1]=h[0]=inf;
        for (int i=1;i<=n;++i){
            while (h[stack.back()]<=h[i])stack.pop_back();
            lft[i]=i-stack.back();
            stack.push_back(i);
        }
        stack.clear();
        stack.push_back(n+1);
        for (int i=n;i>=1;--i){
            while (h[stack.back()]<h[i])stack.pop_back();
            rgt[i]=stack.back()-i;
            stack.push_back(i);
        }
        ll ans = 0;
        for (int i=1;i<=n;++i)ans+=1LL*lft[i]*1LL*rgt[i]*1LL*h[i];
        stack.clear();
        h[0]=h[n+1]=0;
        stack.push_back(0);
        for (int i=1;i<=n;++i){
            while (h[stack.back()]>=h[i])stack.pop_back();
            lft[i]=i-stack.back();
            stack.push_back(i);
        }
        stack.clear();
        stack.push_back(n+1);
        for (int i=n;i>=1;--i){
            while (h[stack.back()]>h[i])stack.pop_back();
            rgt[i]=stack.back()-i;
            stack.push_back(i);
        }
        for (int i=1;i<=n;++i)ans-=1LL*lft[i]*1LL*rgt[i]*1LL*h[i];
        cout<<ans<<endl;
    }
}
全部评论

相关推荐

04-02 10:09
门头沟学院 Java
用微笑面对困难:这里面问题还是很多的,我也不清楚为啥大家会感觉没啥问题。首先就是全栈开发实习9个月的内容都没有java实习生的内容多,1整个技术栈没看出太核心和难点的内容,感觉好像被拉过去打杂了,而且全栈基本上很容易被毙。里面能问的bug是在太多了比如L:继承 BaseMapper 可直接使用内置方法’。请问你的 BaseMapper 是如何扫描实体类注解如果瞬时产生 100 个上传任务,MySQL 的索引设计是否会有瓶颈?你做过分库分表或者索引优化吗?全栈的内容可以针对动态难点去搞,技能特长写在下面吧,你写了这么多技能,项目和实习体现了多少?你可以在项目里多做文章然后把这个放下去,从大致来看实习不算太水,有含金量你也要写上内容针对哨兵里面的节点变化能问出一万个问题,这个很容易就爆了。
提前批简历挂麻了怎么办
点赞 评论 收藏
分享
03-29 18:59
运城学院 Java
程序员小白条:咱们要对自己的简历和学历有清晰的认知,不要动不动就大厂了....都26届了,没实习还想着大厂,唉
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务