Skip to content

Commit d97d5b9

Browse files
upd
1 parent 893d199 commit d97d5b9

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

content/4_Gold/Stacks.problems.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@
196196
"isStarred": false,
197197
"tags": ["Stack"],
198198
"solutionMetadata": {
199-
"kind": "none"
199+
"kind": "internal"
200200
}
201201
},
202202
{

solutions/gold/cses-1148.mdx

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
id: cses-1148
3+
source: CSES
4+
title: Maximum Building II
5+
author: Mihnea Brebenel
6+
prerequisites:
7+
- prefix-sums
8+
---
9+
10+
## Explanation
11+
12+
Precompute $r_{i,j}$ as the maximum number of continuous free cells on line $i$ starting from $(i, j)$ to the right.
13+
Similarly to [Maximum Building I](https://cses.fi/problemset/task/1147) apply monotonic stacks to find:
14+
- $u_{i, j}$ , the last line above $i$ with cell $(x, j)$ such that $r_{x, j} > r_{i, j}$
15+
- $d_{i, j}$ , the last line under $i$ with cell $(y, j)$ such that $r_{y, j} \ge r_{i, j}$
16+
17+
Using [prefix sums](/silver/more-prefix-sums#2d-prefix-sums) and [difference arrays](https://codeforces.com/blog/entry/78762)
18+
we can efficiently update the answer matrix. Having $r_{i,j}$, $u_{i,j}$ and $d_{i,j}$ precomputed, we know the upperbound
19+
and the lowerbound of the rectangle of of width $r_{i,j}$ i.e. how much it can expand above and below line $i$ maintaing width $r_{i, j}$.
20+
We'll do difference arrays on each column independently. Accordingly, the updates of the answer matrix look like this:
21+
- $ans[1][r_{i,j}]++$
22+
- $ans[i - u_{i, j} + 2][r_{i,j}]--$ , the upperbound
23+
- $ans[d_{i,j} - i + 2][r_{i, j}]]--$ , the lowerbound
24+
- $ans[d_{i,j} - u_{i,j} + 3][r_{i,j}]++$
25+
26+
Finally, add $ans[i][j]$ to $ans[i][j-1]$ i.e. a submatrix of size $i \times j$ contains a submatrix of size $i \times (j-1)$.
27+
28+
## Implementation
29+
30+
**Time Complexity:** $\mathcal{O}(N \cdot M)$
31+
32+
<LanguageSection>
33+
<CPPSection>
34+
35+
```cpp
36+
#include <iostream>
37+
#include <vector>
38+
#include <stack>
39+
40+
using namespace std;
41+
42+
int main() {
43+
int n, m;
44+
cin >> n >> m;
45+
vector<vector<int>> r(n + 2, vector<int>(m + 2));
46+
vector<vector<int>> u(n + 2, vector<int>(m + 2));
47+
vector<vector<int>> d(n + 2, vector<int>(m + 2));
48+
vector<vector<int>> ans(n + 3, vector<int>(m + 3));
49+
vector<vector<char>> mat(n + 2, vector<char>(m + 2));
50+
for(int i = 1; i <= n; i++) {
51+
for(int j = 1; j <= m; j++) {
52+
cin >> mat[i][j];
53+
}
54+
for(int j = m; j >= 1; j--) {
55+
if(mat[i][j] == '*') {
56+
r[i][j] = 0;
57+
} else {
58+
r[i][j] = r[i][j + 1] + 1;
59+
}
60+
}
61+
}
62+
stack<int> st;
63+
for(int j = 1; j <= m; j++) {
64+
while(!st.empty()) { st.pop(); }
65+
for(int i = 1; i <= n; i++) {
66+
while(!st.empty() && r[i][j] < r[st.top()][j]) { st.pop(); }
67+
u[i][j] = st.empty() ? 1 : (st.top() + 1);
68+
st.push(i);
69+
}
70+
while(!st.empty()) { st.pop(); }
71+
for(int i = n; i >= 1; i--) {
72+
while(!st.empty() && r[i][j] <= r[st.top()][j]) { st.pop(); }
73+
d[i][j] = st.empty() ? n : (st.top() - 1);
74+
st.push(i);
75+
}
76+
}
77+
for(int i = 1; i <= n; i++) {
78+
for(int j = 1; j <= m; j++) {
79+
ans[1][r[i][j]]++;
80+
ans[i - u[i][j] + 2][r[i][j]]--;
81+
ans[d[i][j] - i + 2][r[i][j]]--;
82+
ans[d[i][j] - u[i][j] + 3][r[i][j]]++;
83+
}
84+
}
85+
for(int j = 1; j <= m; ++j) {
86+
for(int i = 1; i <= n; ++i) {
87+
ans[i][j] += ans[i - 1][j];
88+
}
89+
for(int i = 1; i <= n; ++i) {
90+
ans[i][j] += ans[i - 1][j];
91+
}
92+
}
93+
for(int i = n; i >= 1; --i) {
94+
for(int j = m; j >= 2; --j) {
95+
ans[i][j - 1] += ans[i][j];
96+
}
97+
}
98+
for(int i = 1; i <= n; ++i) {
99+
for(int j = 1; j <= m; ++j) {
100+
cout << ans[i][j] << " ";
101+
}
102+
cout << '\n';
103+
}
104+
}
105+
106+
```
107+
108+
</CPPSection>
109+
</LanguageSection>

0 commit comments

Comments
 (0)