0%

计蒜客38228 Max answer 单调栈 + 线段树

Max answerPOJ 2796 Feel Good类似,但是这个题有负数,需要特殊处理一下

1
2
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);
}
}

/**
5
1 2 3 4 5
5
-1 -2 -3 -4 -5
7
1 2 3 -1 -2 -3 8
7
1 2 3 -1 -2 -3 1
9
1 2 3 -1 -2 -3 8 -100 100

*/