Provided $ f_ {i, j} $ $ I $ is deleted before the number of $ $ j th maximum value, the metastasis $ f_ {i, j} = max (f_ {i-1, j}, f_ { i-1, j-1} + a_i) $.
Proven, we found that for each $ a_i $, there is a $ j $, for all $ dp $ value after the $ j $ and $ j $ are selected on the $ a_i $.
Thus maintenance $ $ DP with a balanced tree, that is updated every time a new point is added, for a section for adding interval arithmetic sequence, a demarcation point to two points, the complexity of $ O (nlog ^ 2n) $.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; namespace { struct node { int f, sz, ch[2]; ll v, d, a; } t[maxn]; int root = 1, Pool = 1; void update(int x) { t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1; } bool wh(int x) { return x == t[t[x].f].ch[1]; } void modify(int x, ll a, ll d) { t[x].d += d; t[x].a += a; t[x].v += a + d * (t[t[x].ch[0]].sz + 1); } void Pushdown(int x) { if(!t[x].d && !t[x].a) return; if(t[x].ch[0]) modify(t[x].ch[0], t[x].a, t[x].d); if(t[x].ch[1]) modify(t[x].ch[1], t[x].a + t[x].d * (t[t[x].ch[0]].sz + 1), t[x].d); t[x].a = t[x].d = 0; } void Push(int x) { if(t[x].f) Push(t[x].f); Pushdown(x); } void rotate(int x) { int f = t[x].f, w = wh(x); t[x].f = t[f].f; t[t[f].f].ch[wh(f)] = x; t[f].ch[w] = t[x].ch[w ^ 1]; t[t[x].ch[w ^ 1]].f = f; t[x].ch[w ^ 1] = f; t[f].f = x; update(f); update(x); } inline void splay(int x, int tar) { Push(x); for(; t[x].f != tar; rotate(x)) if(t[t[x].f].f != tar) rotate(wh(x) == wh(t[x].f) ? t[x].f : x); if(!tar) root = x; } ll find_k(int k) { int x = root; while(1) { if(t[x].ch[0] && t[t[x].ch[0]].sz >= k) x = t[x].ch[0]; else if(t[t[x].ch[0]].sz + 1 < k) k -= t[t[x].ch[0]].sz + 1, x = t[x].ch[1]; else { splay(x, 0); return t[x].v; } } } void Insert() { t[++Pool].v = t[root].v; t[Pool].f = root; t[t[root].ch[1]].f = Pool; t[Pool].ch[1] = t[root].ch[1]; t[root].ch[1] = Pool; } int Query(int i, int x) { int l = 0, r = i, ret = i; while(r - l > 1) { int mid = l + r >> 1; if(find_k(mid) + 1LL * mid * x > find_k(mid + 1)) r = ret = mid; else l = mid; } return ret; } ll dfs(int x) { if(!x) return (ll)(-1e18); Pushdown(x); return max(max(dfs(t[x].ch[0]), dfs(t[x].ch[1])), t[x].v); } } int n; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { int x, k; scanf("%d", &x); k = Query(i, x); find_k(k); Insert(); modify(Pool, 1LL * (k - 1) * x, x); } printf("%lld\n", dfs(root)); return 0; }