Skip to content

Commit 721f6b0

Browse files
committed
feat: add solutions to lc problem: No.2479
No.2479.Maximum XOR of Two Non-Overlapping Subtrees
1 parent 7abb958 commit 721f6b0

File tree

6 files changed

+864
-4
lines changed

6 files changed

+864
-4
lines changed

solution/2400-2499/2479.Maximum XOR of Two Non-Overlapping Subtrees/README.md

Lines changed: 296 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,326 @@
5454

5555
<!-- 这里可写通用的实现逻辑 -->
5656

57+
**方法一:递归 + 0-1 前缀树**
58+
59+
我们先递归预处理出每个节点的子树和,记录在数组 $s$ 中。
60+
61+
然后使用 0-1 前缀树维护遍历过的子树和,可以方便快速查找下一个子树和与之前的子树和的最大异或值。
62+
63+
由于子树不能重叠,因此,我们先查询最大异或值,递归结束后,再将当前子树和插入到前缀树中。
64+
65+
时间复杂度 $O(n \times log M)$,其中 $n$ 为节点个数,而 $M$ 为子树和的最大值。
66+
5767
<!-- tabs:start -->
5868

5969
### **Python3**
6070

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

6373
```python
64-
74+
class Trie:
75+
def __init__(self):
76+
self.children = [None] * 2
77+
78+
def insert(self, x):
79+
node = self
80+
for i in range(47, -1, -1):
81+
v = (x >> i) & 1
82+
if node.children[v] is None:
83+
node.children[v] = Trie()
84+
node = node.children[v]
85+
86+
def search(self, x):
87+
node = self
88+
res = 0
89+
for i in range(47, -1, -1):
90+
v = (x >> i) & 1
91+
if node is None:
92+
return res
93+
if node.children[v ^ 1]:
94+
res = res << 1 | 1
95+
node = node.children[v ^ 1]
96+
else:
97+
res <<= 1
98+
node = node.children[v]
99+
return res
100+
101+
102+
class Solution:
103+
def maxXor(self, n: int, edges: List[List[int]], values: List[int]) -> int:
104+
def dfs1(i, fa):
105+
t = values[i]
106+
for j in g[i]:
107+
if j != fa:
108+
t += dfs1(j, i)
109+
s[i] = t
110+
return t
111+
112+
def dfs2(i, fa):
113+
nonlocal ans
114+
ans = max(ans, tree.search(s[i]))
115+
for j in g[i]:
116+
if j != fa:
117+
dfs2(j, i)
118+
tree.insert(s[i])
119+
120+
g = defaultdict(list)
121+
for a, b in edges:
122+
g[a].append(b)
123+
g[b].append(a)
124+
s = [0] * n
125+
dfs1(0, -1)
126+
ans = 0
127+
tree = Trie()
128+
dfs2(0, -1)
129+
return ans
65130
```
66131

67132
### **Java**
68133

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

71136
```java
72-
137+
class Trie {
138+
Trie[] children = new Trie[2];
139+
140+
void insert(long x) {
141+
Trie node = this;
142+
for (int i = 47; i >= 0; --i) {
143+
int v = (int) (x >> i) & 1;
144+
if (node.children[v] == null) {
145+
node.children[v] = new Trie();
146+
}
147+
node = node.children[v];
148+
}
149+
}
150+
151+
long search(long x) {
152+
Trie node = this;
153+
long res = 0;
154+
for (int i = 47; i >= 0; --i) {
155+
int v = (int) (x >> i) & 1;
156+
if (node == null) {
157+
return res;
158+
}
159+
if (node.children[v ^ 1] != null) {
160+
res = res << 1 | 1;
161+
node = node.children[v ^ 1];
162+
} else {
163+
res <<= 1;
164+
node = node.children[v];
165+
}
166+
}
167+
return res;
168+
}
169+
}
170+
171+
class Solution {
172+
private List<Integer>[] g;
173+
private int[] vals;
174+
private long[] s;
175+
private Trie tree;
176+
private long ans;
177+
178+
public long maxXor(int n, int[][] edges, int[] values) {
179+
g = new List[n];
180+
s = new long[n];
181+
vals = values;
182+
for (int i = 0; i < n; ++i) {
183+
g[i] = new ArrayList<>();
184+
}
185+
for (var e : edges) {
186+
int a = e[0], b = e[1];
187+
g[a].add(b);
188+
g[b].add(a);
189+
}
190+
dfs1(0, -1);
191+
tree = new Trie();
192+
dfs2(0, -1);
193+
return ans;
194+
}
195+
196+
private void dfs2(int i, int fa) {
197+
ans = Math.max(ans, tree.search(s[i]));
198+
for (int j : g[i]) {
199+
if (j != fa) {
200+
dfs2(j, i);
201+
}
202+
}
203+
tree.insert(s[i]);
204+
}
205+
206+
private long dfs1(int i, int fa) {
207+
long t = vals[i];
208+
for (int j : g[i]) {
209+
if (j != fa) {
210+
t += dfs1(j, i);
211+
}
212+
}
213+
s[i] = t;
214+
return t;
215+
}
216+
}
73217
```
74218

75219
### **C++**
76220

77221
```cpp
78-
222+
using ll = long long;
223+
224+
class Trie {
225+
public:
226+
vector<Trie*> children;
227+
string v;
228+
Trie()
229+
: children(2) { }
230+
231+
void insert(ll x) {
232+
Trie* node = this;
233+
for (int i = 47; ~i; --i) {
234+
int v = (x >> i) & 1;
235+
if (!node->children[v]) node->children[v] = new Trie();
236+
node = node->children[v];
237+
}
238+
}
239+
240+
ll search(ll x) {
241+
Trie* node = this;
242+
ll res = 0;
243+
for (int i = 47; ~i; --i) {
244+
if (!node) return res;
245+
int v = (x >> i) & 1;
246+
if (node->children[v ^ 1]) {
247+
res = res << 1 | 1;
248+
node = node->children[v ^ 1];
249+
} else {
250+
res <<= 1;
251+
node = node->children[v];
252+
}
253+
}
254+
return res;
255+
}
256+
};
257+
258+
class Solution {
259+
public:
260+
long long maxXor(int n, vector<vector<int>>& edges, vector<int>& values) {
261+
vector<vector<int>> g(n);
262+
for (auto& e : edges) {
263+
int a = e[0], b = e[1];
264+
g[a].emplace_back(b);
265+
g[b].emplace_back(a);
266+
}
267+
vector<ll> s(n);
268+
function<ll(int, int)> dfs1 = [&](int i, int fa) -> ll {
269+
ll t = values[i];
270+
for (int j : g[i]) {
271+
if (j != fa) t += dfs1(j, i);
272+
}
273+
s[i] = t;
274+
return t;
275+
};
276+
dfs1(0, -1);
277+
Trie tree;
278+
ll ans = 0;
279+
function<void(int, int)> dfs2 = [&](int i, int fa) {
280+
ans = max(ans, tree.search(s[i]));
281+
for (int j : g[i]) {
282+
if (j != fa) {
283+
dfs2(j, i);
284+
}
285+
}
286+
tree.insert(s[i]);
287+
};
288+
dfs2(0, -1);
289+
return ans;
290+
}
291+
};
79292
```
80293
81294
### **Go**
82295
83296
```go
84-
297+
type Trie struct {
298+
children [2]*Trie
299+
}
300+
301+
func newTrie() *Trie {
302+
return &Trie{}
303+
}
304+
305+
func (this *Trie) insert(x int) {
306+
node := this
307+
for i := 47; i >= 0; i-- {
308+
v := (x >> i) & 1
309+
if node.children[v] == nil {
310+
node.children[v] = newTrie()
311+
}
312+
node = node.children[v]
313+
}
314+
}
315+
316+
func (this *Trie) search(x int) int {
317+
node := this
318+
res := 0
319+
for i := 47; i >= 0; i-- {
320+
v := (x >> i) & 1
321+
if node == nil {
322+
return res
323+
}
324+
if node.children[v^1] != nil {
325+
res = res<<1 | 1
326+
node = node.children[v^1]
327+
} else {
328+
res <<= 1
329+
node = node.children[v]
330+
}
331+
}
332+
return res
333+
}
334+
335+
func maxXor(n int, edges [][]int, values []int) int64 {
336+
g := make([][]int, n)
337+
for _, e := range edges {
338+
a, b := e[0], e[1]
339+
g[a] = append(g[a], b)
340+
g[b] = append(g[b], a)
341+
}
342+
s := make([]int, n)
343+
var dfs1 func(i, fa int) int
344+
dfs1 = func(i, fa int) int {
345+
t := values[i]
346+
for _, j := range g[i] {
347+
if j != fa {
348+
t += dfs1(j, i)
349+
}
350+
}
351+
s[i] = t
352+
return t
353+
}
354+
dfs1(0, -1)
355+
ans := 0
356+
tree := newTrie()
357+
var dfs2 func(i, fa int)
358+
dfs2 = func(i, fa int) {
359+
ans = max(ans, tree.search(s[i]))
360+
for _, j := range g[i] {
361+
if j != fa {
362+
dfs2(j, i)
363+
}
364+
}
365+
tree.insert(s[i])
366+
}
367+
dfs2(0, -1)
368+
return int64(ans)
369+
}
370+
371+
func max(a, b int) int {
372+
if a > b {
373+
return a
374+
}
375+
return b
376+
}
85377
```
86378

87379
### **...**

0 commit comments

Comments
 (0)