D. Yet Another Yet Another Task

122 阅读1分钟

题目

Alice and Bob are playing yet another card game. This time the rules are the following. There are nn cards lying in a row in front of them. The ii-th card has value aia_i.

First, Alice chooses a non-empty consecutive segment of cards [l;r][l; r] (lrl \le r). After that Bob removes a single card jj from that segment (ljr)(l \le j \le r). The score of the game is the total value of the remaining cards on the segment (al+al+1++aj1+aj+1++ar1+ar)(a_l + a_{l + 1} + \dots + a_{j - 1} + a_{j + 1} + \dots + a_{r - 1} + a_r). In particular, if Alice chooses a segment with just one element, then the score after Bob removes the only card is 00.

Alice wants to make the score as big as possible. Bob takes such a card that the score is as small as possible.

What segment should Alice choose so that the score is maximum possible? Output the maximum score.

输入

The first line contains a single integer nn (1n1051 \le n \le 10^5) — the number of cards.

The second line contains nn integers a1,a2,,ana_1, a_2, \dots, a_n (30ai30-30 \le a_i \le 30) — the values on the cards.

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <stack>
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
#define endl '\n'
#define pb push_back
#define NO cout << "NO" << endl;
#define YES cout << "YES" << endl;
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
typedef vector<int> VI;
typedef pair<int,int> PII;
ll MOD;
ll powmod(ll a,ll b) {ll res=1;a%=MOD; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
mt19937 mrand(random_device{}()); 
const int N = 2e5 + 10;
int a[N], L[N], R[N], b[N], s[N];
int stk[N], que;
int st[N][21], lg[N], lk[N][21];
int n;
void init() {
    for(int i = 1; i <= n + 1; i++) {
        st[i][0] = s[i - 1];
        lk[i][0] = a[i - 1];
        if(i >= 2) {
            lg[i] = lg[i / 2] + 1;
        }
    }
    for(int j = 1; j < 21; j++) {
        for(int i = 1; i + (1 << j) - 1 <= n + 1; i++) {
            st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
            lk[i][j] = max(lk[i][j - 1], lk[i + (1 << (j - 1))][j - 1]);
        }
    }
}

ll calc(int l, int r) {
    if(l > r) return 0;
    int t = lg[r - l + 1];
    return min({st[l][t], st[r - (1 << t) + 1][t]});
}
ll check(int l, int r) {
    int t = lg[r - l + 1];
    return max(lk[l][t], lk[r - (1 << t) + 1][t]);
}
void solve()
{
    cin >> n;
    rep(i, 1, n) cin >> a[i];
    rep(i, 1, n) s[i] = s[i - 1] + a[i];
    a[0] = -1e9;
    init();
    for(int i = 1; i <= n; i++) {
        int l = 0, r = i;
        while(l <= r) {
            int mid = l + r >> 1;
            if(check(mid + 1,i + 1) <= a[i]) r = mid - 1;
            else l = mid + 1;
        }
        // cout << l << ' ';
        if(l != i) {
            L[i] = s[i - 1] - calc(l + 1, i) ;
        }
    }
    reverse(a + 1, a + 1 + n);
    rep(i, 1, n) s[i] = s[i - 1] + a[i];
    // rep(i, 1, n) cout << a[i] << " \n"[i == n];
    init();
     for(int i = 1; i <= n; i++) {
        int l = 0, r = i;
        ll ans = 0;
        while(l <= r) {
            int mid = l + r >> 1;
            if(check(mid + 1,i + 1) <= a[i]) r = mid - 1;
            else l = mid + 1;
        }
        // cout << l << " \n"[ i == n];
        if(l != i) {
            R[i] = s[i - 1] - calc(l + 1, i) ;
        }
    }
    // rep(i, 1, n) cout << L[i] << " \n"[ i == n ];
    // rep(i, 1, n) cout << R[i] << " \n"[ i == n ];
    ll res = 0;
    rep(i, 1, n) res = max(res, L[i] + R[n - i + 1]);
    cout << res << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    // int T;cin >> T;
    // while ( T -- )
    solve();
    return 0;
}