Skip to content

Commit 3eacb1c

Browse files
committed
feat: add solutions to lc problem: No.2158
No.2158.Amount of New Area Painted Each Day
1 parent 5598320 commit 3eacb1c

File tree

5 files changed

+847
-0
lines changed

5 files changed

+847
-0
lines changed

solution/2100-2199/2158.Amount of New Area Painted Each Day/README.md

+292
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,314 @@ The amount of new area painted on day 1 is 0.
6868

6969
<!-- 这里可写通用的实现逻辑 -->
7070

71+
**方法一:线段树**
72+
73+
线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 `log(width)`。更新某个元素的值,只需要更新 `log(width)` 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用**懒标记**保证效率。
74+
75+
- 线段树的每个节点代表一个区间;
76+
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 `[1, N]`
77+
- 线段树的每个叶子节点代表一个长度为 1 的元区间 `[x, x]`
78+
- 对于每个内部节点 `[l, r]`,它的左儿子是 `[l, mid]`,右儿子是 `[mid + 1, r]`, 其中 `mid = ⌊(l + r) / 2⌋` (即向下取整)。
79+
80+
对于本题,线段树节点维护的信息有:
81+
82+
1. 区间中元素大于 0 的个数 v
83+
1. 懒标记 add
84+
7185
<!-- tabs:start -->
7286

7387
### **Python3**
7488

7589
<!-- 这里可写当前语言的特殊实现逻辑 -->
7690

7791
```python
92+
class Node:
93+
def __init__(self, l, r):
94+
self.left = None
95+
self.right = None
96+
self.l = l
97+
self.r = r
98+
self.mid = (l + r) >> 1
99+
self.v = 0
100+
self.add = 0
101+
102+
103+
class SegmentTree:
104+
def __init__(self):
105+
self.root = Node(1, 10**5 + 10)
106+
107+
def modify(self, l, r, v, node=None):
108+
if l > r:
109+
return
110+
if node is None:
111+
node = self.root
112+
if node.l >= l and node.r <= r:
113+
node.v = node.r - node.l + 1
114+
node.add = v
115+
return
116+
self.pushdown(node)
117+
if l <= node.mid:
118+
self.modify(l, r, v, node.left)
119+
if r > node.mid:
120+
self.modify(l, r, v, node.right)
121+
self.pushup(node)
122+
123+
def query(self, l, r, node=None):
124+
if l > r:
125+
return 0
126+
if node is None:
127+
node = self.root
128+
if node.l >= l and node.r <= r:
129+
return node.v
130+
self.pushdown(node)
131+
v = 0
132+
if l <= node.mid:
133+
v += self.query(l, r, node.left)
134+
if r > node.mid:
135+
v += self.query(l, r, node.right)
136+
return v
78137

138+
def pushup(self, node):
139+
node.v = node.left.v + node.right.v
140+
141+
def pushdown(self, node):
142+
if node.left is None:
143+
node.left = Node(node.l, node.mid)
144+
if node.right is None:
145+
node.right = Node(node.mid + 1, node.r)
146+
if node.add:
147+
left, right = node.left, node.right
148+
left.v = left.r - left.l + 1
149+
right.v = right.r - right.l + 1
150+
left.add = node.add
151+
right.add = node.add
152+
node.add = 0
153+
154+
155+
class Solution:
156+
def amountPainted(self, paint: List[List[int]]) -> List[int]:
157+
tree = SegmentTree()
158+
ans = []
159+
for i, (start, end) in enumerate(paint):
160+
l, r = start + 1, end
161+
v = tree.query(l, r)
162+
ans.append(r - l + 1 - v)
163+
tree.modify(l, r, 1)
164+
return ans
79165
```
80166

81167
### **Java**
82168

83169
<!-- 这里可写当前语言的特殊实现逻辑 -->
84170

85171
```java
172+
class Node {
173+
Node left;
174+
Node right;
175+
int l;
176+
int r;
177+
int mid;
178+
int v;
179+
int add;
180+
181+
public Node(int l, int r) {
182+
this.l = l;
183+
this.r = r;
184+
this.mid = (l + r) >> 1;
185+
}
186+
}
187+
188+
class SegmentTree {
189+
private Node root = new Node(1, 100010);
190+
191+
public SegmentTree() {
192+
193+
}
194+
195+
public void modify(int l, int r, int v) {
196+
modify(l, r, v, root);
197+
}
198+
199+
public void modify(int l, int r, int v, Node node) {
200+
if (l > r) {
201+
return;
202+
}
203+
if (node.l >= l && node.r <= r) {
204+
node.v = node.r - node.l + 1;
205+
node.add = v;
206+
return;
207+
}
208+
pushdown(node);
209+
if (l <= node.mid) {
210+
modify(l, r, v, node.left);
211+
}
212+
if (r > node.mid) {
213+
modify(l, r, v, node.right);
214+
}
215+
pushup(node);
216+
}
217+
218+
public int query(int l, int r) {
219+
return query(l, r, root);
220+
}
221+
222+
public int query(int l, int r, Node node) {
223+
if (l > r) {
224+
return 0;
225+
}
226+
if (node.l >= l && node.r <= r) {
227+
return node.v;
228+
}
229+
pushdown(node);
230+
int v = 0;
231+
if (l <= node.mid) {
232+
v += query(l, r, node.left);
233+
}
234+
if (r > node.mid) {
235+
v += query(l, r, node.right);
236+
}
237+
return v;
238+
}
239+
240+
public void pushup(Node node) {
241+
node.v = node.left.v + node.right.v;
242+
}
243+
244+
public void pushdown(Node node) {
245+
if (node.left == null) {
246+
node.left = new Node(node.l, node.mid);
247+
}
248+
if (node.right == null) {
249+
node.right = new Node(node.mid + 1, node.r);
250+
}
251+
if (node.add != 0) {
252+
Node left = node.left, right = node.right;
253+
left.add = node.add;
254+
right.add = node.add;
255+
left.v = left.r - left.l + 1;
256+
right.v = right.r - right.l + 1;
257+
node.add = 0;
258+
}
259+
}
260+
}
261+
262+
class Solution {
263+
public int[] amountPainted(int[][] paint) {
264+
SegmentTree tree = new SegmentTree();
265+
int n = paint.length;
266+
int[] ans = new int[n];
267+
for (int i = 0; i < n; ++i) {
268+
int l = paint[i][0] + 1;
269+
int r = paint[i][1];
270+
int v = tree.query(l, r);
271+
ans[i] = r - l + 1 - v;
272+
tree.modify(l, r, 1);
273+
}
274+
return ans;
275+
}
276+
}
277+
```
278+
279+
### **C++**
280+
281+
```cpp
282+
class Node {
283+
public:
284+
Node* left;
285+
Node* right;
286+
int l;
287+
int r;
288+
int mid;
289+
int v;
290+
int add;
291+
292+
Node(int l, int r) {
293+
this->l = l;
294+
this->r = r;
295+
this->mid = (l + r) >> 1;
296+
this->left = this->right = nullptr;
297+
v = add = 0;
298+
}
299+
};
300+
301+
class SegmentTree {
302+
private:
303+
Node* root;
304+
305+
public:
306+
SegmentTree() {
307+
root = new Node(1, 100010);
308+
}
309+
310+
void modify(int l, int r, int v) {
311+
modify(l, r, v, root);
312+
}
313+
314+
void modify(int l, int r,int v, Node* node) {
315+
if (l > r) return;
316+
if (node->l >= l && node->r <= r)
317+
{
318+
node->v = node->r - node->l + 1;
319+
node->add = v;
320+
return;
321+
}
322+
pushdown(node);
323+
if (l <= node->mid) modify(l, r, v, node->left);
324+
if (r > node->mid) modify(l, r, v, node->right);
325+
pushup(node);
326+
}
327+
328+
int query(int l, int r) {
329+
return query(l, r, root);
330+
}
331+
332+
int query(int l, int r, Node* node) {
333+
if (l > r) return 0;
334+
if (node->l >= l && node-> r <= r) return node->v;
335+
pushdown(node);
336+
int v = 0;
337+
if (l <= node->mid) v += query(l, r, node->left);
338+
if (r > node->mid) v += query(l, r, node->right);
339+
return v;
340+
}
341+
342+
void pushup(Node* node) {
343+
node->v = node->left->v + node->right->v;
344+
}
345+
346+
void pushdown(Node* node) {
347+
if (!node->left) node->left = new Node(node->l, node->mid);
348+
if (!node->right) node->right = new Node(node->mid + 1, node->r);
349+
if (node->add)
350+
{
351+
Node* left = node->left;
352+
Node* right = node->right;
353+
left->v = left->r - left->l + 1;
354+
right->v = right->r - right->l + 1;
355+
left->add = node->add;
356+
right->add = node->add;
357+
node->add = 0;
358+
}
359+
}
360+
};
86361

362+
class Solution {
363+
public:
364+
vector<int> amountPainted(vector<vector<int>>& paint) {
365+
int n = paint.size();
366+
vector<int> ans(n);
367+
SegmentTree* tree = new SegmentTree();
368+
for (int i = 0; i < n; ++i)
369+
{
370+
int l = paint[i][0] + 1;
371+
int r = paint[i][1];
372+
int v = tree->query(l, r);
373+
ans[i] = r - l + 1 - v;
374+
tree->modify(l, r, 1);
375+
}
376+
return ans;
377+
}
378+
};
87379
```
88380
89381
### **TypeScript**

0 commit comments

Comments
 (0)