Skip to content

Commit c76b81e

Browse files
committed
feat: add solutions to lc problem: No.0850
No.0850.Rectangle Area II
1 parent c2f4a98 commit c76b81e

File tree

5 files changed

+767
-0
lines changed

5 files changed

+767
-0
lines changed

solution/0800-0899/0850.Rectangle Area II/README.md

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,288 @@
4949

5050
<!-- 这里可写通用的实现逻辑 -->
5151

52+
**方法一:离散化 + 线段树 + 扫描线**
53+
54+
线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 `log(width)`。更新某个元素的值,只需要更新 `log(width)` 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用**懒标记**保证效率。
55+
56+
- 线段树的每个节点代表一个区间;
57+
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 `[1, N]`
58+
- 线段树的每个叶子节点代表一个长度为 1 的元区间 `[x, x]`
59+
- 对于每个内部节点 `[l, r]`,它的左儿子是 `[l, mid]`,右儿子是 `[mid + 1, r]`, 其中 `mid = ⌊(l + r) / 2⌋` (即向下取整)。
60+
61+
对于本题,线段树节点维护的信息有:
62+
63+
1. 区间被覆盖的次数 cnt;
64+
1. 区间被覆盖的长度 len。
65+
5266
<!-- tabs:start -->
5367

5468
### **Python3**
5569

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

5872
```python
73+
class Node:
74+
def __init__(self):
75+
self.l = 0
76+
self.r = 0
77+
self.cnt = 0
78+
self.length = 0
79+
80+
81+
class SegmentTree:
82+
def __init__(self, nums):
83+
n = len(nums) - 1
84+
self.nums = nums
85+
self.tr = [Node() for _ in range(n << 2)]
86+
self.build(1, 0, n - 1)
87+
88+
def build(self, u, l, r):
89+
self.tr[u].l, self.tr[u].r = l, r
90+
if l != r:
91+
mid = (l + r) >> 1
92+
self.build(u << 1, l, mid)
93+
self.build(u << 1 | 1, mid + 1, r)
5994

95+
def modify(self, u, l, r, k):
96+
if self.tr[u].l >= l and self.tr[u].r <= r:
97+
self.tr[u].cnt += k
98+
else:
99+
mid = (self.tr[u].l + self.tr[u].r) >> 1
100+
if l <= mid:
101+
self.modify(u << 1, l, r, k)
102+
if r > mid:
103+
self.modify(u << 1 | 1, l, r, k)
104+
self.pushup(u)
105+
106+
def pushup(self, u):
107+
if self.tr[u].cnt:
108+
self.tr[u].length = self.nums[self.tr[u].r + 1] - \
109+
self.nums[self.tr[u].l]
110+
elif self.tr[u].l == self.tr[u].r:
111+
self.tr[u].length = 0
112+
else:
113+
self.tr[u].length = self.tr[u << 1].length + \
114+
self.tr[u << 1 | 1].length
115+
116+
@property
117+
def length(self):
118+
return self.tr[1].length
119+
120+
121+
class Solution:
122+
def rectangleArea(self, rectangles: List[List[int]]) -> int:
123+
segs = []
124+
alls = set()
125+
for x1, y1, x2, y2 in rectangles:
126+
segs.append((x1, y1, y2, 1))
127+
segs.append((x2, y1, y2, -1))
128+
alls.add(y1)
129+
alls.add(y2)
130+
alls = sorted(alls)
131+
m = {v: i for i, v in enumerate(alls)}
132+
tree = SegmentTree(alls)
133+
segs.sort()
134+
ans = 0
135+
for i, (x, y1, y2, k) in enumerate(segs):
136+
if i > 0:
137+
ans += tree.length * (x - segs[i - 1][0])
138+
tree.modify(1, m[y1], m[y2] - 1, k)
139+
ans %= int(1e9 + 7)
140+
return ans
60141
```
61142

62143
### **Java**
63144

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

66147
```java
148+
class Node {
149+
int l;
150+
int r;
151+
int cnt;
152+
int len;
153+
}
154+
155+
class SegmentTree {
156+
private Node[] tr;
157+
private int[] nums;
158+
159+
public SegmentTree(int[] nums) {
160+
int n = nums.length - 1;
161+
this.nums = nums;
162+
tr = new Node[n << 2];
163+
for (int i = 0; i < tr.length; ++i) {
164+
tr[i] = new Node();
165+
}
166+
build(1, 0, n - 1);
167+
}
168+
169+
public void build(int u, int l, int r) {
170+
tr[u].l = l;
171+
tr[u].r = r;
172+
if (l != r) {
173+
int mid = (l + r) >> 1;
174+
build(u << 1, l, mid);
175+
build(u << 1 | 1, mid + 1, r);
176+
}
177+
}
178+
179+
public void modify(int u, int l, int r, int k) {
180+
if (tr[u].l >= l && tr[u].r <= r) {
181+
tr[u].cnt += k;
182+
} else {
183+
int mid = (tr[u].l + tr[u].r) >> 1;
184+
if (l <= mid) {
185+
modify(u << 1, l, r, k);
186+
}
187+
if (r > mid) {
188+
modify(u << 1 | 1, l, r, k);
189+
}
190+
}
191+
pushup(u);
192+
}
193+
194+
public int query() {
195+
return tr[1].len;
196+
}
197+
198+
public void pushup(int u) {
199+
if (tr[u].cnt > 0) {
200+
tr[u].len = nums[tr[u].r + 1] - nums[tr[u].l];
201+
} else if (tr[u].l == tr[u].r) {
202+
tr[u].len = 0;
203+
} else {
204+
tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
205+
}
206+
}
207+
}
208+
209+
class Solution {
210+
private static final int MOD = (int) 1e9 + 7;
211+
212+
public int rectangleArea(int[][] rectangles) {
213+
int n = rectangles.length;
214+
int[][] segs = new int[n << 1][4];
215+
int idx = 0;
216+
TreeSet<Integer> ts = new TreeSet<>();
217+
for (int[] rect : rectangles) {
218+
int x1 = rect[0], y1 = rect[1], x2 = rect[2], y2 = rect[3];
219+
segs[idx++] = new int[]{x1, y1, y2, 1};
220+
segs[idx++] = new int[]{x2, y1, y2, -1};
221+
ts.add(y1);
222+
ts.add(y2);
223+
}
224+
Map<Integer, Integer> m = new HashMap<>();
225+
int[] nums = new int[ts.size()];
226+
idx = 0;
227+
for (int v : ts) {
228+
nums[idx] = v;
229+
m.put(v, idx++);
230+
}
231+
Arrays.sort(segs, Comparator.comparingInt(a -> a[0]));
232+
SegmentTree tree = new SegmentTree(nums);
233+
long ans = 0;
234+
for (int i = 0; i < segs.length; ++i) {
235+
int x = segs[i][0], y1 = segs[i][1], y2 = segs[i][2], k = segs[i][3];
236+
if (i > 0) {
237+
ans += (long) tree.query() * (x - segs[i - 1][0]);
238+
}
239+
tree.modify(1, m.get(y1), m.get(y2) - 1, k);
240+
}
241+
ans %= MOD;
242+
return (int) ans;
243+
}
244+
}
245+
```
246+
247+
### **C++**
248+
249+
```cpp
250+
class Node {
251+
public:
252+
int l, r, cnt, len;
253+
};
254+
255+
class SegmentTree {
256+
private:
257+
vector<Node*> tr;
258+
vector<int> nums;
259+
260+
public:
261+
SegmentTree(vector<int>& nums) {
262+
int n = nums.size() - 1;
263+
this->nums = nums;
264+
tr.resize(n << 2);
265+
for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
266+
build(1, 0, n - 1);
267+
}
268+
269+
void build(int u, int l, int r) {
270+
tr[u]->l = l;
271+
tr[u]->r = r;
272+
if (l != r)
273+
{
274+
int mid = (l + r) >> 1;
275+
build(u << 1, l, mid);
276+
build(u << 1 | 1, mid + 1, r);
277+
}
278+
}
279+
280+
void modify(int u, int l, int r, int k) {
281+
if (tr[u]->l >= l && tr[u]->r <= r) tr[u]->cnt += k;
282+
else
283+
{
284+
int mid = (tr[u]->l + tr[u]->r) >> 1;
285+
if (l <= mid) modify(u << 1, l, r, k);
286+
if (r > mid) modify(u << 1 | 1, l, r, k);
287+
}
288+
pushup(u);
289+
}
290+
291+
int query() {
292+
return tr[1]->len;
293+
}
294+
295+
void pushup(int u) {
296+
if (tr[u]->cnt) tr[u]->len = nums[tr[u]->r + 1] - nums[tr[u]->l];
297+
else if (tr[u]->l == tr[u]->r) tr[u]->len = 0;
298+
else tr[u]->len = tr[u << 1]->len + tr[u << 1 | 1]->len;
299+
}
300+
};
67301

302+
class Solution {
303+
public:
304+
int rectangleArea(vector<vector<int>>& rectangles) {
305+
int n = rectangles.size();
306+
vector<vector<int>> segs;
307+
set<int> ts;
308+
int mod = 1e9 + 7;
309+
for (auto& rect : rectangles)
310+
{
311+
int x1 = rect[0], y1 = rect[1], x2 = rect[2], y2 = rect[3];
312+
segs.push_back({x1, y1, y2, 1});
313+
segs.push_back({x2, y1, y2, -1});
314+
ts.insert(y1);
315+
ts.insert(y2);
316+
}
317+
unordered_map<int, int> m;
318+
int idx = 0;
319+
for (int v : ts) m[v] = idx++;
320+
sort(segs.begin(), segs.end());
321+
vector<int> nums(ts.begin(), ts.end());
322+
SegmentTree* tree = new SegmentTree(nums);
323+
long long ans = 0;
324+
for (int i = 0; i < segs.size(); ++i)
325+
{
326+
int x = segs[i][0], y1 = segs[i][1], y2 = segs[i][2], k = segs[i][3];
327+
if (i > 0) ans += (long long) tree->query() * (x - segs[i - 1][0]);
328+
tree->modify(1, m[y1], m[y2] - 1, k);
329+
}
330+
ans %= mod;
331+
return (int) ans;
332+
}
333+
};
68334
```
69335
70336
### **...**

0 commit comments

Comments
 (0)