Skip to content

Commit 60d2cef

Browse files
committed
feat: add solutions to lcp problem: No.05
LCP 05. 发 LeetCoin
1 parent 580bf13 commit 60d2cef

File tree

4 files changed

+699
-1
lines changed

4 files changed

+699
-1
lines changed

lcp/LCP 05. 发 LeetCoin/README.md

+356-1
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,377 @@
7272

7373
<!-- 这里可写通用的实现逻辑 -->
7474

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

7786
### **Python3**
7887

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

8190
```python
82-
91+
MOD = int(1e9 + 7)
92+
93+
94+
class Node:
95+
def __init__(self, l, r):
96+
self.left = None
97+
self.right = None
98+
self.l = l
99+
self.r = r
100+
self.mid = (l + r) >> 1
101+
self.v = 0
102+
self.add = 0
103+
104+
105+
class SegmentTree:
106+
def __init__(self, n):
107+
self.root = Node(1, n)
108+
109+
def modify(self, l, r, v, node=None):
110+
if l > r:
111+
return
112+
if node is None:
113+
node = self.root
114+
if node.l >= l and node.r <= r:
115+
node.v = (node.v + (node.r - node.l + 1) * v) % MOD
116+
node.add += v
117+
return
118+
self.pushdown(node)
119+
if l <= node.mid:
120+
self.modify(l, r, v, node.left)
121+
if r > node.mid:
122+
self.modify(l, r, v, node.right)
123+
self.pushup(node)
124+
125+
def query(self, l, r, node=None):
126+
if l > r:
127+
return 0
128+
if node is None:
129+
node = self.root
130+
if node.l >= l and node.r <= r:
131+
return node.v
132+
self.pushdown(node)
133+
v = 0
134+
if l <= node.mid:
135+
v += self.query(l, r, node.left)
136+
if r > node.mid:
137+
v += self.query(l, r, node.right)
138+
return v % MOD
139+
140+
def pushup(self, node):
141+
node.v = (node.left.v + node.right.v) % MOD
142+
143+
def pushdown(self, node):
144+
if node.left is None:
145+
node.left = Node(node.l, node.mid)
146+
if node.right is None:
147+
node.right = Node(node.mid + 1, node.r)
148+
if node.add:
149+
left, right = node.left, node.right
150+
left.v = (left.v + (left.r - left.l + 1) * node.add) % MOD
151+
right.v = (right.v + (right.r - right.l + 1) * node.add) % MOD
152+
left.add += node.add
153+
right.add += node.add
154+
node.add = 0
155+
156+
157+
class Solution:
158+
def bonus(self, n: int, leadership: List[List[int]], operations: List[List[int]]) -> List[int]:
159+
def dfs(u):
160+
nonlocal idx
161+
begin[u] = idx
162+
for v in g[u]:
163+
dfs(v)
164+
end[u] = idx
165+
idx += 1
166+
167+
g = defaultdict(list)
168+
for a, b in leadership:
169+
g[a].append(b)
170+
begin = [0] * (n + 1)
171+
end = [0] * (n + 1)
172+
idx = 1
173+
dfs(1)
174+
ans = []
175+
tree = SegmentTree(n)
176+
for op in operations:
177+
p, v = op[:2]
178+
if p == 1:
179+
tree.modify(end[v], end[v], op[2])
180+
elif p == 2:
181+
tree.modify(begin[v], end[v], op[2])
182+
else:
183+
ans.append(tree.query(begin[v], end[v]))
184+
return ans
83185
```
84186

85187
### **Java**
86188

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

89191
```java
192+
class Node {
193+
Node left;
194+
Node right;
195+
int l;
196+
int r;
197+
int mid;
198+
int v;
199+
int add;
200+
public Node(int l, int r) {
201+
this.l = l;
202+
this.r = r;
203+
this.mid = (l + r) >> 1;
204+
}
205+
}
206+
207+
class SegmentTree {
208+
private Node root;
209+
private static final int MOD = (int) 1e9 + 7;
210+
211+
public SegmentTree(int n) {
212+
root = new Node(1, n);
213+
}
214+
215+
public void modify(int l, int r, int v) {
216+
modify(l, r, v, root);
217+
}
218+
219+
public void modify(int l, int r, int v, Node node) {
220+
if (l > r) {
221+
return;
222+
}
223+
if (node.l >= l && node.r <= r) {
224+
node.v = (node.v + (node.r - node.l + 1) * v) % MOD;
225+
node.add += v;
226+
return;
227+
}
228+
pushdown(node);
229+
if (l <= node.mid) {
230+
modify(l, r, v, node.left);
231+
}
232+
if (r > node.mid) {
233+
modify(l, r, v, node.right);
234+
}
235+
pushup(node);
236+
}
237+
238+
public int query(int l, int r) {
239+
return query(l, r, root);
240+
}
241+
242+
public int query(int l, int r, Node node) {
243+
if (l > r) {
244+
return 0;
245+
}
246+
if (node.l >= l && node.r <= r) {
247+
return node.v;
248+
}
249+
pushdown(node);
250+
int v = 0;
251+
if (l <= node.mid) {
252+
v = (v + query(l, r, node.left)) % MOD;
253+
}
254+
if (r > node.mid) {
255+
v = (v + query(l, r, node.right)) % MOD;
256+
}
257+
return v;
258+
}
259+
260+
public void pushup(Node node) {
261+
node.v = (node.left.v + node.right.v) % MOD;
262+
}
263+
264+
public void pushdown(Node node) {
265+
if (node.left == null) {
266+
node.left = new Node(node.l, node.mid);
267+
}
268+
if (node.right == null) {
269+
node.right = new Node(node.mid + 1, node.r);
270+
}
271+
if (node.add != 0) {
272+
Node left = node.left, right = node.right;
273+
left.v = (left.v + (left.r - left.l + 1) * node.add) % MOD;
274+
right.v = (right.v + (right.r - right.l + 1) * node.add) % MOD;
275+
left.add += node.add;
276+
right.add += node.add;
277+
node.add = 0;
278+
}
279+
}
280+
}
281+
282+
class Solution {
283+
private List<Integer>[] g;
284+
private int[] begin;
285+
private int[] end;
286+
private int idx;
287+
288+
public int[] bonus(int n, int[][] leadership, int[][] operations) {
289+
g = new List[n + 1];
290+
for (int i = 0; i < g.length; ++i) {
291+
g[i] = new ArrayList<>();
292+
}
293+
for (int[] l : leadership) {
294+
int a = l[0], b = l[1];
295+
g[a].add(b);
296+
}
297+
begin = new int[n + 1];
298+
end = new int[n + 1];
299+
idx = 1;
300+
dfs(1);
301+
List<Integer> ans = new ArrayList<>();
302+
SegmentTree tree = new SegmentTree(n);
303+
for (int[] op : operations) {
304+
int p = op[0], v = op[1];
305+
if (p == 1) {
306+
tree.modify(end[v], end[v], op[2]);
307+
} else if (p == 2) {
308+
tree.modify(begin[v], end[v], op[2]);
309+
} else {
310+
ans.add(tree.query(begin[v], end[v]));
311+
}
312+
}
313+
return ans.stream().mapToInt(Integer::intValue).toArray();
314+
}
315+
316+
private void dfs(int u) {
317+
begin[u] = idx;
318+
for (int v : g[u]) {
319+
dfs(v);
320+
}
321+
end[u] = idx;
322+
++idx;
323+
}
324+
}
325+
```
90326

327+
### **C++**
328+
329+
```cpp
330+
const int MOD = 1e9 + 7;
331+
332+
class Node {
333+
public:
334+
Node* left;
335+
Node* right;
336+
int l;
337+
int r;
338+
int mid;
339+
int v;
340+
int add;
341+
342+
Node(int l, int r) {
343+
this->l = l;
344+
this->r = r;
345+
this->mid = (l + r) >> 1;
346+
this->left = this->right = nullptr;
347+
v = add = 0;
348+
}
349+
};
350+
351+
class SegmentTree {
352+
private:
353+
Node* root;
354+
355+
public:
356+
SegmentTree(int n) {
357+
root = new Node(1, n);
358+
}
359+
360+
void modify(int l, int r, int v) {
361+
modify(l, r, v, root);
362+
}
363+
364+
void modify(int l, int r,int v, Node* node) {
365+
if (l > r) return;
366+
if (node->l >= l && node->r <= r)
367+
{
368+
node->v = (node->v + (node->r - node->l + 1) * v) % MOD;
369+
node->add += v;
370+
return;
371+
}
372+
pushdown(node);
373+
if (l <= node->mid) modify(l, r, v, node->left);
374+
if (r > node->mid) modify(l, r, v, node->right);
375+
pushup(node);
376+
}
377+
378+
int query(int l, int r) {
379+
return query(l, r, root);
380+
}
381+
382+
int query(int l, int r, Node* node) {
383+
if (l > r) return 0;
384+
if (node->l >= l && node-> r <= r) return node->v;
385+
pushdown(node);
386+
int v = 0;
387+
if (l <= node->mid) v += query(l, r, node->left);
388+
if (r > node->mid) v += query(l, r, node->right);
389+
return v % MOD;
390+
}
391+
392+
void pushup(Node* node) {
393+
node->v = (node->left->v + node->right->v) % MOD;
394+
}
395+
396+
void pushdown(Node* node) {
397+
if (!node->left) node->left = new Node(node->l, node->mid);
398+
if (!node->right) node->right = new Node(node->mid + 1, node->r);
399+
if (node->add)
400+
{
401+
Node* left = node->left;
402+
Node* right = node->right;
403+
left->v = (left->v + (left->r - left->l + 1) * node->add) % MOD;
404+
right->v = (right->v + (right->r - right->l + 1) * node->add) % MOD;
405+
left->add += node->add;
406+
right->add += node->add;
407+
node->add = 0;
408+
}
409+
}
410+
};
411+
412+
class Solution {
413+
public:
414+
int idx;
415+
416+
vector<int> bonus(int n, vector<vector<int>>& leadership, vector<vector<int>>& operations) {
417+
vector<vector<int>> g(n + 1);
418+
for (auto& l : leadership)
419+
{
420+
int a = l[0], b = l[1];
421+
g[a].push_back(b);
422+
}
423+
vector<int> begin(n + 1);
424+
vector<int> end(n + 1);
425+
idx = 1;
426+
dfs(1, begin, end, g);
427+
vector<int> ans;
428+
SegmentTree* tree = new SegmentTree(n);
429+
for (auto& op : operations)
430+
{
431+
int p = op[0], v = op[1];
432+
if (p == 1) tree->modify(end[v], end[v], op[2]);
433+
else if (p == 2) tree->modify(begin[v], end[v], op[2]);
434+
else ans.push_back(tree->query(begin[v], end[v]));
435+
}
436+
return ans;
437+
}
438+
439+
void dfs(int u, vector<int>& begin, vector<int>& end, vector<vector<int>>& g) {
440+
begin[u] = idx;
441+
for (int v : g[u]) dfs(v, begin, end, g);
442+
end[u] = idx;
443+
++idx;
444+
}
445+
};
91446
```
92447
93448
### **...**

0 commit comments

Comments
 (0)