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
| # 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
import sys
from collections import deque
input = sys.stdin.readline
def compute_best(depth, m, n, HBoundIn, WBoundIn):
N = m * n
HBound = min(HBoundIn, m)
WBound = min(WBoundIn, n)
best = 0
col_deq = [deque() for _ in range(n)]
M = [0] * n
left = [0] * n
right = [0] * n
st = [0] * n
for h in range(1, HBound + 1):
for c in range(n):
col_deq[c].clear()
for r in range(m):
row = depth[r]
for c in range(n):
dc = col_deq[c]
val = row[c]
while dc and dc[-1][0] >= val:
dc.pop()
dc.append((val, r))
if r >= h - 1:
start = r - h + 1
for c in range(n):
dc = col_deq[c]
while dc and dc[0][1] < start:
dc.popleft()
M[c] = dc[0][0]
top = -1
for c in range(n):
while top >= 0 and M[st[top]] >= M[c]:
top -= 1
left[c] = st[top] if top >= 0 else -1
top += 1
st[top] = c
top = -1
for c in range(n - 1, -1, -1):
while top >= 0 and M[st[top]] >= M[c]:
top -= 1
right[c] = st[top] if top >= 0 else n
top += 1
st[top] = c
for c in range(n):
width_span = right[c] - left[c] - 1
if width_span <= 0:
continue
w = width_span if width_span < WBound else WBound
if w <= 0:
continue
A = h * w
if A >= N:
continue
numer = N * M[c] - 1
if numer <= 0:
continue
denom = N - A
H = numer // denom
if H <= 0:
continue
V = A * H
if V > best:
best = V
return best
def main():
a, b, m, n = map(int, input().split())
depth = [list(map(int, input().split())) for _ in range(m)]
ans = 0
ans = max(ans, compute_best(depth, m, n, a, b))
ans = max(ans, compute_best(depth, m, n, b, a))
print(ans)
if __name__ == "__main__":
main()
|