玄关求条(马蜂良好)
查看原帖
玄关求条(马蜂良好)
1007305
Terry_RE楼主2025/8/31 15:17

思路是比较以每一个 aia_i 为最大值的区间内 aia_i包含 aia_i 的最大的连续子段和

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 2e5+7;

int lmx[N];
int rmx[N];

ll lsum[N], rsum[N];

int n;
int a[N];

void Sol(){
    cin >> n;

    for(int i(1); i <= n; ++i)
        cin >> a[i];

    stack<int> sk;

    for(int i(1); i <= n; ++i){
        while(!sk.empty() && a[sk.top()] <= a[i])
            sk.pop();

        lmx[i] = sk.empty() ? 1 : sk.top() + 1;

        sk.push(i);
    }

    while(!sk.empty())
        sk.pop();

    for(int i(n); i >= 1; --i){
        while(!sk.empty() && a[sk.top()] <= a[i])
            sk.pop();

        rmx[i] = sk.empty() ? n : sk.top() - 1;

        sk.push(i);
    }

    for(int i(1); i <= n; ++i)
        if(i == lmx[i])
            lsum[i] = a[i];
        else
            lsum[i] = max((ll)a[i], lsum[i-1] + a[i]);

    for(int i(n); i >= 1; --i)
        if(i == rmx[i])
            rsum[i] = a[i];
        else
            rsum[i] = max((ll)a[i], rsum[i+1] + a[i]);

    // for(int i(1); i <= n; ++i)
    //     cout << lmx[i] << ' ' << rmx[i] << endl;

    for(int i(1); i <= n; ++i)
        if(a[i] < lsum[i] + rsum[i] - a[i])
            return cout << "NO\n", void();

    cout << "YES\n";
}

int main(){
    cin.tie(0) -> ios::sync_with_stdio(false);

    int T = 1;
    cin >> T;

    while(T--)
        Sol();

    return 0;
}
2025/8/31 15:17
加载中...