题目 codeforce 1851F
数据结构:0-1字典树
算法:局部贪心
作用:维护异或极值,从左到右依次插入,判断极值。
解题思路
- 根据公式,推导性质。 ( a i ⊕ x ) & ( a j ⊕ x ) (a_i\oplus x) \& (a_j\oplus x) (ai⊕x)&(aj⊕x) 从高位到低位依次贪心,如果两个数的相同,则可以转化位1,对应x上的数应该取反。举例如果ai和aj的某位都是1,则x取0,经过异或,两个都变成1,然后经过与运算,还是1。相反ai和aj都是0,则x取1。
- 使用0-1字典树,遍历插入,并计算最大值。
时间复杂度:O(n)
空间复杂度:unknown
相似题目:力扣421,数组中两个数的最大异或值
参考代码
class TrieNode:
def __init__(self):
self.children = [None] * 2
self.idx = -1
class Trie:
def __init__(self, h):
self.h = h
self.root = TrieNode()
def insert(self, num, idx):
node = self.root
for i in range(self.h - 1, -1, -1):
lr = (num >> i) & 1
if node.children[lr] is None:
node.children[lr] = TrieNode()
node = node.children[lr]
node.idx = idx
def minimum_xor(self, num):
mx = 0
mask = 0
node = self.root
for i in range(self.h - 1, -1, -1):
lr = (num >> i) & 1
if node.children[lr]:
node = node.children[lr]
if lr == 0:
mask |= (1 << i)
mx |= (1 << i)
elif node.children[lr ^ 1]:
node = node.children[lr ^ 1]
else:
print('break')
break
return mx, mask, node.idx
def solve(n, k, nums):
trie = Trie(k)
trie.insert(nums[0], 0)
ans = 0
l, r, x = 0, 1, 0
for j, num in enumerate(nums[1:]):
mx, mask, i = trie.minimum_xor(num)
if mx > ans:
ans = mx
l, r, x = i, j + 1, mask
trie.insert(num, j + 1)
print(l + 1, r + 1, x)
# print(f"max: {(nums[l] ^ x) & (nums[r] ^ x)}")
def main():
tcn = int(input())
for _ in range(tcn):
n, k = map(int, input().split())
nums = list(map(int, input().split()))
solve(n, k, nums)