| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 
 | #include <bits/stdc++.h>#define DBG(x) cerr << #x << " = " << x << endl
 
 using namespace std;
 typedef long long LL;
 
 #define iall 1, n, 1
 #define lrrt int l, int r, int rt
 #define lson l, mid, rt << 1
 #define rson mid + 1, r, rt << 1 | 1
 
 const int MAXN = 500000 + 16;
 const LL INF = 0x7F7F7F7F7F7F7F7F;
 LL a[MAXN], sum[MAXN];
 LL max_tree[MAXN << 2], min_tree[MAXN << 2];
 int STK[MAXN], top;
 int L[MAXN], R[MAXN];
 int n;
 
 void build(lrrt) {
 max_tree[rt] = min_tree[rt] = 0;
 if (l == r) {
 return;
 }
 int mid = (l + r) >> 1;
 build(lson);
 build(rson);
 }
 
 void add(lrrt, int x, int v) {
 if (l == r) {
 max_tree[rt] = min_tree[rt] = v;
 return;
 }
 int mid = (l + r) >> 1;
 if (x <= mid) add(lson, x, v);
 else add(rson, x, v);
 max_tree[rt] = max(max_tree[rt << 1], max_tree[rt << 1 | 1]);
 min_tree[rt] = min(min_tree[rt << 1], min_tree[rt << 1 | 1]);
 }
 
 LL query_min(lrrt, int x, int y) {
 if (x <= l && r <= y) {
 return min_tree[rt];
 }
 int mid = (l + r) >> 1;
 if (x > mid) return query_min(rson, x, y);
 else if (y <= mid) return query_min(lson, x, y);
 else return min(query_min(lson, x, y), query_min(rson, x, y));
 }
 
 LL query_max(lrrt, int x, int y) {
 if (x <= l && r <= y) {
 return max_tree[rt];
 }
 int mid = (l + r) >> 1;
 if (x > mid) return query_max(rson, x, y);
 else if (y <= mid) return query_max(lson, x, y);
 else return max(query_max(lson, x, y), query_max(rson, x, y));
 }
 
 LL get_max(int x, int y) {
 if (y == 0)
 return 0;
 if (x == 0) {
 return max(LL(0), query_max(iall, 1, y));
 }
 return query_max(iall, x, y);
 }
 
 void get_lr() {
 top = 0;
 for (int i = 1; i <= n; ++i) {
 L[i] = i;
 while (top && a[i] < a[STK[top]]) {
 L[i] = L[STK[top]];
 R[STK[top]] = i - 1;
 --top;
 }
 STK[++top] = i;
 }
 while (top) {
 R[STK[top--]] = n;
 }
 }
 
 int main(int argc, char **argv) {
 while (~scanf("%d", &n)) {
 for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]); a[n + 1] = -INF;
 for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + a[i];
 get_lr();
 build(iall);
 for (int i = 1; i <= n; ++i) add(iall, i, sum[i]);
 LL ans = -INF;
 for (int i = 1; i <= n; ++i) {
 if (a[i] >= 0) {
 LL tmp = a[i] * (sum[R[i]] - sum[L[i] - 1]);
 ans = max(ans, tmp);
 } else {
 LL sr = query_min(iall, i, R[i]);
 LL sl = get_max(L[i] - 1, i - 1);
 LL tmp = a[i] * (sr - sl);
 ans = max(ans, tmp);
 }
 }
 printf("%lld\n", ans);
 }
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 |