Codeforces Round #622 (Div. 2)C2

Posted luoyugongxi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #622 (Div. 2)C2相关的知识,希望对你有一定的参考价值。

题意

N长度为500000以内,一个数字两边的数字不能都比他高,最多高一边

求他最大sum。叙述有问题,直接看样例

3

10 6 8

因为6左右都比他高,选择10 6 6或者6 6  8,sum明显前者高

所以答案输出10 6 6

思路:

求出每个a[i]左边(minl[i])和右边(minl[i])最近的一个比他小的数,用前缀和(suml) 和 后缀和(sumr)求得当a[i]是顶点时候sum=suml+sumr-a[i];

前缀和如果minl[i]==空集(0),那么suml[i]=i*a[i];如果minl[i]有位置,suml[i]=suml[minl[i]]+(i-minl[i])*a[i];

后缀和如果minr[i]==空集(n+1),那么sumr[i]=(n+1-i)*a[i];如果minr[i]有位置,sumr[i]=sumr[minr[i]]+(minr[i]-i)*a[i];

 

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define il inline
 5 #define it register int
 6 #define inf 0x3f3f3f3f
 7 #define lowbit(x) (x)&(-x)
 8 #define mem(a,b) memset(a,b,sizeof(a))
 9 #define modd 998244353
10 const int maxn=5e5+10;
11 int n;
12 ll a[maxn],b[maxn],minl[maxn],minr[maxn],suml[maxn],sumr[maxn];
13 stack<int>st;
14 int main(){
15     scanf("%d",&n);
16     for(it i=1;i<=n;i++){scanf("%lld",&a[i]);}
17     for(it i=1;i<=n;i++){
18         while(st.size()&&a[st.top()]>=a[i]){st.pop();}
19         if(st.empty()){minl[i]=0;}
20         else{minl[i]=st.top();}
21         st.push(i);
22     }
23     while(st.size()){st.pop();}
24     for(it i=n;i>=1;i--){
25         while(st.size()&&a[st.top()]>=a[i]){st.pop();}
26         if(st.empty()){minr[i]=n+1;}
27         else{minr[i]=st.top();}
28         st.push(i);
29     }
30     for(it i=1;i<=n;i++){
31         if(!minl[i]){suml[i]=(ll)i*a[i];}
32         else{
33             suml[i]=suml[minl[i]]+(ll)(i-minl[i])*a[i];
34         }
35     }
36     for(it i=n;i>=1;i--){
37         if(minr[i]==n+1){sumr[i]=(ll)(minr[i]-i)*a[i];}
38         else{
39             sumr[i]=sumr[minr[i]]+(ll)(minr[i]-i)*a[i];
40         }
41     }
42     ll ans=-1;int pos;
43     for(it i=1;i<=n;i++){
44         ll zz=sumr[i]+suml[i]-a[i];
45         //cout<<sumr[i]<<" "<<minr[i]<<" "<<suml[i]<<endl;
46         if(zz>ans){
47             ans=zz,pos=i;
48         }
49     }
50 
51     b[pos]=a[pos];ll zhi=a[pos];
52     for(it i=pos+1;i<=n;i++){
53         if(a[i]<zhi){
54             zhi=a[i];
55         }
56         b[i]=zhi;
57     }
58     zhi=a[pos];
59     for(it i=pos-1;i>0;i--){
60         if(a[i]<zhi){
61             zhi=a[i];
62         }
63         b[i]=zhi;
64     }
65     for(it i=1;i<=n;i++){
66         printf(i==n?"%lld
":"%lld ",b[i]);
67     }
68     return 0;
69 }
View Code

 

以上是关于Codeforces Round #622 (Div. 2)C2的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #622 (Div. 2)C(单调栈,DP)

Codeforces Round #622 (Div. 2)C2

CodeForces 622D Optimal Number Permutation

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)

Codeforces Round #622 (Div. 2) 题解和我的分析

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 单调栈