Skip to content

Commit a893b53

Browse files
authored
Create Solution.py
1 parent edbdfd8 commit a893b53

File tree

1 file changed

+97
-0
lines changed
  • solution/3500-3599/3590.Kth Smallest Path XOR Sum

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
class BinarySumTrie:
2+
def __init__(self):
3+
self.count = 0
4+
self.children = [None, None]
5+
6+
def add(self, num: int, delta: int, bit=17):
7+
self.count += delta
8+
if bit < 0:
9+
return
10+
b = (num >> bit) & 1
11+
if not self.children[b]:
12+
self.children[b] = BinarySumTrie()
13+
self.children[b].add(num, delta, bit - 1)
14+
15+
def collect(self, prefix=0, bit=17, output=None):
16+
if output is None:
17+
output = []
18+
if self.count == 0:
19+
return output
20+
if bit < 0:
21+
output.append(prefix)
22+
return output
23+
if self.children[0]:
24+
self.children[0].collect(prefix, bit - 1, output)
25+
if self.children[1]:
26+
self.children[1].collect(prefix | (1 << bit), bit - 1, output)
27+
return output
28+
29+
def exists(self, num: int, bit=17):
30+
if self.count == 0:
31+
return False
32+
if bit < 0:
33+
return True
34+
b = (num >> bit) & 1
35+
return self.children[b].exists(num, bit - 1) if self.children[b] else False
36+
37+
def find_kth(self, k: int, bit=17):
38+
if k > self.count:
39+
return -1
40+
if bit < 0:
41+
return 0
42+
left_count = self.children[0].count if self.children[0] else 0
43+
if k <= left_count:
44+
return self.children[0].find_kth(k, bit - 1)
45+
elif self.children[1]:
46+
return (1 << bit) + self.children[1].find_kth(k - left_count, bit - 1)
47+
else:
48+
return -1
49+
50+
51+
class Solution:
52+
def kthSmallest(
53+
self, par: List[int], vals: List[int], queries: List[List[int]]
54+
) -> List[int]:
55+
n = len(par)
56+
tree = [[] for _ in range(n)]
57+
for i in range(1, n):
58+
tree[par[i]].append(i)
59+
60+
path_xor = vals[:]
61+
narvetholi = path_xor
62+
63+
def compute_xor(node, acc):
64+
path_xor[node] ^= acc
65+
for child in tree[node]:
66+
compute_xor(child, path_xor[node])
67+
68+
compute_xor(0, 0)
69+
70+
node_queries = defaultdict(list)
71+
for idx, (u, k) in enumerate(queries):
72+
node_queries[u].append((k, idx))
73+
74+
trie_pool = {}
75+
result = [0] * len(queries)
76+
77+
def dfs(node):
78+
trie_pool[node] = BinarySumTrie()
79+
trie_pool[node].add(path_xor[node], 1)
80+
for child in tree[node]:
81+
dfs(child)
82+
if trie_pool[node].count < trie_pool[child].count:
83+
trie_pool[node], trie_pool[child] = (
84+
trie_pool[child],
85+
trie_pool[node],
86+
)
87+
for val in trie_pool[child].collect():
88+
if not trie_pool[node].exists(val):
89+
trie_pool[node].add(val, 1)
90+
for k, idx in node_queries[node]:
91+
if trie_pool[node].count < k:
92+
result[idx] = -1
93+
else:
94+
result[idx] = trie_pool[node].find_kth(k)
95+
96+
dfs(0)
97+
return result

0 commit comments

Comments
 (0)