• 【POJ2796】Feel Good 单调栈


    题目大意:给定一个长度为 N 的序列,求任意区间 [ l , r ] 中最小的(min{v[i],iin[l,r] }*Sigma_{i=l}^rv[i])

    题解:这是一道具有标准单调栈特征的问题,即:区间最小值贡献类问题。直接枚举每个点为最小值时用单调栈求出左右最远的延伸距离,并利用前缀和预处理进行答案统计即可。

    代码如下

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=1e5+10;
    
    inline int read(){
    	int x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    
    int n,v[maxn],stk[maxn],top,l[maxn],r[maxn];
    long long ans=-1,sum[maxn];
    
    void read_and_parse(){
    	n=read();
    	for(int i=1;i<=n;i++)v[i]=read(),sum[i]=sum[i-1]+v[i];
    }
    
    void solve(){
    	v[0]=v[n+1]=-1;//这里卡了半天 QAQ
    	for(int i=1;i<=n+1;i++){
    		while(top&&v[stk[top]]>v[i])r[stk[top--]]=i-1;
    		stk[++top]=i;
    	}
    	top=0;
    	for(int i=n;i>=0;i--){
    		while(top&&v[i]<v[stk[top]])l[stk[top--]]=i+1;
    		stk[++top]=i;
    	}
    	int x,y;
    	for(int i=1;i<=n;i++){
    		long long src=(sum[r[i]]-sum[l[i]-1])*v[i];
    		if(src>ans)ans=src,x=l[i],y=r[i];
    	}
    	printf("%lld
    %d %d
    ",ans,x,y);
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    关于mysql 中schema的相关操作
    ASP.NET Core MVC 之过滤器(Filter)
    docker-Error: No such container
    java多种加密和解密方式
    linux 下的rpm 和ivh各是什么意思
    新生赛题目准备
    Figma 学习笔记 – Keyboard Shortcut and Tips 小技巧
    Figma 学习笔记 – Frame
    Chart.js 学习笔记
    SQL Server STRING_AGG
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10066610.html
Copyright © 2020-2023  润新知