Skip to content

Commit 6612fe5

Browse files
committed
feat: 2271. Maximum White Tiles Covered by a Carpet : 线段树
1 parent 17ae684 commit 6612fe5

File tree

3 files changed

+124
-5
lines changed

3 files changed

+124
-5
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
function maximumWhiteTiles (tiles: number[][], carpetLen: number): number {
2+
const tree = new SegmentTree(0, 1e9)
3+
for (const [l, r] of tiles) {
4+
tree.modifyRange(l, r, 1)
5+
}
6+
let ans = 0
7+
for (const [l, r] of tiles) {
8+
const { sum } = tree.query(l, Math.min(l + carpetLen - 1, 1e9))
9+
ans = Math.max(ans, sum)
10+
}
11+
return ans
12+
};
13+
14+
export declare const a: 1
15+
16+
class Node {
17+
start: number
18+
end: number
19+
max: number = 0
20+
sum: number = 0
21+
lazy: number | null = null
22+
left: null | Node = null
23+
right: null | Node = null
24+
constructor (start: number, end: number) {
25+
this.start = start
26+
this.end = end
27+
}
28+
}
29+
30+
// https://www.acwing.com/activity/content/code/content/167900/
31+
class SegmentTree {
32+
root: Node
33+
constructor (start: number, end: number) {
34+
this.root = new Node(start, end)
35+
}
36+
37+
modify (pos: number, val: number) {
38+
this.modifyNode(this.root, pos, val)
39+
}
40+
41+
modifyNode (node: Node, pos: number, val: number) {
42+
if (node.start === pos && node.end === pos) {
43+
node.max = node.sum = val
44+
} else {
45+
this.pushdown(node)
46+
if (pos <= node.left!.end) this.modifyNode(node.left!, pos, val)
47+
if (pos >= node.right!.start) this.modifyNode(node.right!, pos, val)
48+
this.pushup(node)
49+
}
50+
}
51+
52+
// 使用 modify 和 modifyRange 是等价的,modifyRange 更加通用
53+
modifyRange (start: number, end: number, val: number) {
54+
this.modifyNodeRange(this.root, start, end, val)
55+
}
56+
57+
modifyNodeRange (node: Node, start: number, end: number, val: number) {
58+
if (start <= node.start && end >= node.end) {
59+
node.sum = val * (node.end - node.start + 1)
60+
node.max = val
61+
node.lazy = val
62+
} else {
63+
this.pushdown(node)
64+
if (start <= node.left!.end) this.modifyNodeRange(node.left!, start, end, val)
65+
if (end >= node.right!.start) this.modifyNodeRange(node.right!, start, end, val)
66+
this.pushup(node)
67+
}
68+
}
69+
70+
// 这里 pushdown 同时保证了 left, right 一定存在
71+
pushdown (node: Node) {
72+
const mid = node.start + node.end >> 1
73+
node.left ??= new Node(node.start, mid)
74+
node.right ??= new Node(mid + 1, node.end)
75+
if (node.lazy != null) {
76+
node.left.lazy = node.lazy
77+
node.left.max = node.lazy
78+
node.left.sum = node.lazy * (node.left.end - node.left.start + 1)
79+
80+
node.right.lazy = node.lazy
81+
node.right.max = node.lazy
82+
node.right.sum = node.lazy * (node.right.end - node.right.start + 1)
83+
84+
node.lazy = null
85+
}
86+
}
87+
88+
pushup (node: Node) {
89+
node.max = Math.max(node.left!.max, node.right!.max)
90+
node.sum = node.left!.sum + node.right!.sum
91+
}
92+
93+
query (start: number, end: number) {
94+
return this.queryNode(this.root, start, end)
95+
}
96+
97+
queryNode (node: Node, start: number, end: number) {
98+
if (start <= node.start && end >= node.end) {
99+
return { max: node.max, sum: node.sum }
100+
}
101+
102+
this.pushdown(node)
103+
let max = 0; let sum = 0
104+
if (start <= node.left!.end) {
105+
const { max: _m, sum: _s } = this.queryNode(node.left!, start, end)
106+
max = Math.max(max, _m)
107+
sum += _s
108+
}
109+
if (end >= node.right!.start) {
110+
const { max: _m, sum: _s } = this.queryNode(node.right!, start, end)
111+
max = Math.max(max, _m)
112+
sum += _s
113+
}
114+
return { max, sum }
115+
}
116+
}

leetcode/残酷刷题/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@
283283
- 715. Range Module
284284
- 2213. Longest Substring of One Repeating Character
285285
- 2286. Booking Concert Tickets in Groups
286+
- 2271. Maximum White Tiles Covered by a Carpet
286287

287288
## Links
288289

template-typescript.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ class SegmentTree {
570570

571571
modifyNodeRange (node: Node, start: number, end: number, val: number) {
572572
if (start <= node.start && end >= node.end) {
573-
node.sum = val * (end - start + 1)
573+
node.sum = val * (node.end - node.start + 1)
574574
node.max = val
575575
node.lazy = val
576576
} else {
@@ -609,21 +609,23 @@ class SegmentTree {
609609
}
610610

611611
queryNode (node: Node, start: number, end: number) {
612-
if (start <= node.start && end >= node.end) return [node.max, node.sum]
612+
if (start <= node.start && end >= node.end) {
613+
return { max: node.max, sum: node.sum }
614+
}
613615

614616
this.pushdown(node)
615617
let max = 0; let sum = 0
616618
if (start <= node.left!.end) {
617-
const [_m, _s] = this.queryNode(node.left!, start, end)
619+
const { max: _m, sum: _s } = this.queryNode(node.left!, start, end)
618620
max = Math.max(max, _m)
619621
sum += _s
620622
}
621623
if (end >= node.right!.start) {
622-
const [_m, _s] = this.queryNode(node.right!, start, end)
624+
const { max: _m, sum: _s } = this.queryNode(node.right!, start, end)
623625
max = Math.max(max, _m)
624626
sum += _s
625627
}
626-
return [max, sum]
628+
return { max, sum }
627629
}
628630
}
629631

0 commit comments

Comments
 (0)