思路:我们需要维护当下标为inx的大楼为最高的时候,两边大楼的情况。我们可以把下标为inx的大楼最高时,分别统计左边和右边的情况,我们可以用单调栈维护最小值(小->大),如果栈顶的元素的高度小于inx的大楼,说明之前的所有大楼都因为栈顶的大楼而小于了inx的大楼的高度,如果栈顶的大楼高度大于等于inx的大楼,则说明栈顶下面第一个的大楼到栈顶的大楼之间的大楼需要改变为inx大楼的高度,需要注意空栈的情况。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <functional> 5 #include <set> 6 #include <vector> 7 #include <queue> 8 #include <cstring> 9 #include <stack> 10 11 using namespace std; 12 13 #define ll long long 14 #define pb push_back 15 #define fi first 16 #define se second 17 18 19 void solve(){ 20 int n; 21 cin >> n; 22 vector<int > a(n); 23 for(auto& in : a) cin >> in; 24 stack<int > Sta; 25 vector<ll > pre(n); 26 for(int now = 0; now < n; ++now){ 27 while(!Sta.empty()){ 28 int top = Sta.top(); 29 if(a[top] >= a[now]){ 30 Sta.pop(); 31 if(!Sta.empty()){ 32 pre[now] += (ll)a[now] * (top - (int)Sta.top()); 33 }else { 34 pre[now] += (ll)a[now] * (top + 1); 35 } 36 }else { 37 pre[now] += pre[top]; 38 break; 39 } 40 } 41 Sta.push(now); 42 pre[now] += a[now]; 43 } 44 // for(int i = 0; i < n; ++i) cout << pre[i] << " "; 45 // cout << endl; 46 vector<ll > rpre(n); 47 while(!Sta.empty()) Sta.pop(); 48 vector<int > cp(a); 49 reverse(a.begin(), a.end()); 50 for(int now = 0; now < n; ++now){ 51 while(!Sta.empty()){ 52 int top = Sta.top(); 53 if(a[top] >= a[now]){ 54 Sta.pop(); 55 if(!Sta.empty()){ 56 rpre[now] += (ll)a[now] * (top - (int)Sta.top()); 57 }else { 58 rpre[now] += (ll)a[now] * (top + 1); 59 } 60 }else { 61 rpre[now] += rpre[top]; 62 break; 63 } 64 } 65 Sta.push(now); 66 rpre[now] += a[now]; 67 } 68 // for(auto& x : rpre) cout << x << " "; 69 // cout << endl; 70 int inx = 0; 71 //cp[i]被算了两次,需要减去一次 72 for(int i = 1; i < n; ++i){ 73 inx = (pre[i] + rpre[n - 1 - i] - cp[i] > pre[inx] + rpre[n - 1 - inx] - cp[inx] ? i : inx); 74 } 75 // cout << "inx = " << inx << endl; 76 int Min = cp[inx]; 77 vector<int > ans(n); 78 for(int i = inx; i >= 0; --i){ 79 Min = min(Min, cp[i]); 80 ans[i] = Min; 81 } 82 Min = cp[inx]; 83 for(int i = inx + 1; i < n; ++i){ 84 Min = min(Min, cp[i]); 85 ans[i] = Min; 86 } 87 for(auto x : ans) cout << x << " "; 88 cout << endl; 89 90 } 91 92 int main(){ 93 94 ios::sync_with_stdio(false); 95 cin.tie(0); 96 cout.tie(0); 97 solve(); 98 99 return 0; 100 }