这道题目可以当作结论来记住了
相当于用的时间复杂度求:可以求出所有长度为的连续子数组里最小值的最大值

  • 首先如果所有长度为的最小值中的最大值为,那么一定满足
我们可以求如果以当前为最小值的最大区间,那么需要找到向左第一个小于的值的位置,向右第一个小于的值的位置,那么区间的长度为,那么:
ans[r[i] - l[i] - 1] = max(ans[r[i] - l[i] - 1], a[i]);
这样找到最长的区间,对于长度小于的区间的最大值一定大于等于,所以我只需要求最长区间,最后:
for(int i = n - 1; i >= 1; i --) ans[i] = max(ans[i], ans[i + 1]);

如何求,可以用单调栈的知识,栈里面存储的是下标:
for(int i = 1; i <= n; i ++){
        while(sta.size() && a[sta.top()] >= a[i]) sta.pop();
        if(sta.size()) l[i] = sta.top();
        else l[i] = 0;
        sta.push(i);
    }


总代码:
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;


void solve(){

    int n; cin >> n;
    vector<int> a(n + 10), l(n + 10), r(n + 10), ans(n + 10);
    for(int i = 1; i <= n; i ++) cin >> a[i];   
    stack<int> sta;
    for(int i = 1; i <= n; i ++){
        while(sta.size() && a[sta.top()] >= a[i]) sta.pop();
        if(sta.size()) l[i] = sta.top();
        else l[i] = 0;
        sta.push(i);
    } 
    while(sta.size()) sta.pop();
    for(int i = n; i >= 1; i --){
        while(sta.size() && a[sta.top()] >= a[i]) sta.pop();
        if(sta.size()) r[i] = sta.top();
        else r[i] = n + 1;
        sta.push(i);
    } 
    for(int i = 1; i <= n; i ++){
        ans[r[i] - l[i] - 1] = max(ans[r[i] - l[i] - 1], a[i]);
    }
    for(int i = n - 1; i >= 1; i --) ans[i] = max(ans[i], ans[i + 1]);
    for(int i = 1; i <= n; i ++) cout << ans[i] << " ";
    cout << endl;
    return ;
}

signed main(){
    HelloWorld;

    int tt = 1; 
    while(tt --) solve();
    return 0;
}

同样也是单调栈的使用,更加的直白,codeforce题目增加了思维

总代码:
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;


void solve(){

    int n; cin >> n;
    vector<int> a(n + 10), l(n + 10), r(n + 10);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    stack<int> sta;
    for(int i = 1; i <= n; i ++){
        while(sta.size() && a[sta.top()] >= a[i]) sta.pop();
        if(sta.size()) l[i] = sta.top();
        else l[i] = 0;
        sta.push(i);
    }
    while(sta.size()) sta.pop();
    for(int i = n; i >= 1; i --){
        while(sta.size() && a[sta.top()] >= a[i]) sta.pop();
        if(sta.size()) r[i] = sta.top();
        else r[i] = n + 1;
        sta.push(i);
    }
    int ans = 0;
    for(int i = 1; i <= n; i ++){
        ans = max(ans, (r[i] - l[i] - 1) * a[i]);
    }
    cout << ans << endl;
    return ;
}

signed main(){
    HelloWorld;

    int tt = 1; 
    while(tt --) solve();
    return 0;
}