构造出的结果一定是一个单峰/\这种样子的
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 long long a[500007]; 5 pair<long long,long long>stk[500007]; 6 long long l[500007],r[500007];//记录左/右边最近的比当前小的位置 7 long long ans[500007]; 8 long long dp[5][500007];//dp[0][i]表示当a[i]在1~i上单调增时,高度的前缀和,dp[1][i]表示a[i]在i~n单调减时,高度的后缀和(单调可以平,相邻可以相等) 9 int main(){ 10 ios::sync_with_stdio(false); 11 cin.tie(NULL); 12 cout.tie(NULL); 13 int n; 14 cin>>n; 15 for(int i=1;i<=n;++i) 16 cin>>a[i]; 17 int cnt=0; 18 for(int i=1;i<=n;++i){ 19 if(cnt==0||stk[cnt].first<a[i]) 20 stk[++cnt]=make_pair(a[i],i); 21 while(cnt>0&&stk[cnt].first>=a[i]){ 22 l[stk[cnt].second]=stk[cnt-1].second; 23 r[stk[cnt].second]=i; 24 --cnt; 25 } 26 stk[++cnt]=make_pair(a[i],i); 27 } 28 while(cnt){ 29 l[stk[cnt].second]=stk[cnt-1].second; 30 r[stk[cnt].second]=1+n; 31 --cnt; 32 } 33 for(int i=1;i<=n;++i) 34 if(a[i]>a[i-1]) 35 dp[0][i]=dp[0][i-1]+a[i]; 36 else//前面比自己大 37 dp[0][i]=dp[0][l[i]]+(i-l[i])*a[i];//找到i左边最近的比它小的,l[i]~i之间全都砍为a[l[i]] 38 for(int i=n;i;--i) 39 if(a[i]>a[i+1]) 40 dp[1][i]=dp[1][i+1]+a[i]; 41 else//后面比自己大 42 dp[1][i]=dp[1][r[i]]+(r[i]-i)*a[i];//找到i右边最近的比它小的,i~r[i]之间全都砍为a[r[i]] 43 long long mx=0,pos=0,now=0; 44 for(int i=1;i<=n;++i) 45 if(dp[0][i]+dp[1][i]-a[i]>mx){ 46 mx=dp[0][i]+dp[1][i]-a[i]; 47 pos=i; 48 } 49 ans[pos]=a[pos]; 50 now=a[pos]; 51 for(int i=1+pos;i<=n;++i) 52 if(a[i]>=now) 53 ans[i]=now; 54 else{ 55 ans[i]=a[i]; 56 now=a[i]; 57 } 58 now=a[pos]; 59 for(int i=pos-1;i;--i) 60 if(a[i]>=now) 61 ans[i]=now; 62 else{ 63 ans[i]=a[i]; 64 now=a[i]; 65 } 66 for(int i=1;i<=n;++i) 67 cout<<ans[i]<<" "; 68 return 0; 69 }
原文地址:https://www.cnblogs.com/ldudxy/p/12365462.html
时间: 2024-10-08 13:39:39