Codeforces Round #622 (Div. 2)C(单调栈,DP)
2024-09-06 19:32:25
构造出的结果一定是一个单峰/\这种样子的
#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
long long a[];
pair<long long,long long>stk[];
long long l[],r[];//记录左/右边最近的比当前小的位置
long long ans[];
long long dp[][];//dp[0][i]表示当a[i]在1~i上单调增时,高度的前缀和,dp[1][i]表示a[i]在i~n单调减时,高度的后缀和(单调可以平,相邻可以相等)
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin>>n;
for(int i=;i<=n;++i)
cin>>a[i];
int cnt=;
for(int i=;i<=n;++i){
if(cnt==||stk[cnt].first<a[i])
stk[++cnt]=make_pair(a[i],i);
while(cnt>&&stk[cnt].first>=a[i]){
l[stk[cnt].second]=stk[cnt-].second;
r[stk[cnt].second]=i;
--cnt;
}
stk[++cnt]=make_pair(a[i],i);
}
while(cnt){
l[stk[cnt].second]=stk[cnt-].second;
r[stk[cnt].second]=+n;
--cnt;
}
for(int i=;i<=n;++i)
if(a[i]>a[i-])
dp[][i]=dp[][i-]+a[i];
else//前面比自己大
dp[][i]=dp[][l[i]]+(i-l[i])*a[i];//找到i左边最近的比它小的,l[i]~i之间全都砍为a[l[i]]
for(int i=n;i;--i)
if(a[i]>a[i+])
dp[][i]=dp[][i+]+a[i];
else//后面比自己大
dp[][i]=dp[][r[i]]+(r[i]-i)*a[i];//找到i右边最近的比它小的,i~r[i]之间全都砍为a[r[i]]
long long mx=,pos=,now=;
for(int i=;i<=n;++i)
if(dp[][i]+dp[][i]-a[i]>mx){
mx=dp[][i]+dp[][i]-a[i];
pos=i;
}
ans[pos]=a[pos];
now=a[pos];
for(int i=+pos;i<=n;++i)
if(a[i]>=now)
ans[i]=now;
else{
ans[i]=a[i];
now=a[i];
}
now=a[pos];
for(int i=pos-;i;--i)
if(a[i]>=now)
ans[i]=now;
else{
ans[i]=a[i];
now=a[i];
}
for(int i=;i<=n;++i)
cout<<ans[i]<<" ";
return ;
}
最新文章
- Hive_数据倾斜处理
- EXCEL IF 函数 模糊查询
- C# Winform程序本地化应用
- 转 --maven系列之一 简介
- 前端魔法堂:解秘FOUC
- JavaScript的8行代码搞定js文件引入问题
- ------- 当前全球最新的 IPv4 地址池使用报告 -------
- Android BLE与终端通信(二)——Android Bluetooth基础科普以及搜索蓝牙设备显示列表
- 2018-2019-2 20165325 网络对抗技术 Exp4 恶意代码分析
- Dynamics 365 Online-Microsoft Flow
- linux之systemd---学习
- JavaScript(ES5)使用保留字作函数名
- jmeter源码导入eclipse并执行
- win7下python2.6如何安装setuptools和pip
- 消息队列1:RabbitMQ解析并基于Springboot实战
- ACE .i .inl文件(转)
- windows下编译和安装boost库
- wcf配置参数说明
- 对volatile不具有原子性的理解
- Android 相关重难点知识整理