LC 100124. 找出强数对的最大异或值 II

https://leetcode.cn/problems/maximum-strong-pair-xor-ii/

这题大概思路是先求解y的特性,然后看看怎么快速地从符合条件的y里面找到异或最大值。

如果x<=y的话,那么可以得到 x <= y <= 2 * x. 所以我们只需要维护一个数据结构,这个数据结构里面都是 x <= y <= 2 * x 的值就行。这个用双指针就可以搞定。

接着就是这个数据结构了。要求接异或最大值的话,最直接的办法就是维护0,1的二叉树。鉴于其实nums[i]值的范围在[0,2^20)以内,所以这个二叉树可以使用树状数组来实现。

我们每次需要从这个数据结构里面删除和加入某些值的分支,并且更新分支上的值,这个数据结构就是线段树。

最后就是其实判断分支的方法可以写成许多的if-else, 但是也可以简化成下面这样的方式 `p = 2 * p + (1 - b)` 或者是 `p = 2 * p + b`. 代码看起来会更加简单。

这里使用的是 `(p-N)^x` 计算最后的xor结果,在搜索路径上我们其实也可以得到 xor 之后的值。

#!/usr/bin/env python
# coding:utf-8
# Copyright (C) dirlt

from typing import List


class Solution:
    def maximumStrongPairXor(self, nums: List[int]) -> int:
        nums.sort()
        MAXB = 20
        N = 1 << MAXB
        tree = [0] * (2 * N)

        def update(x, v):
            p = N + x
            tree[p] = v
            while p != 1:
                p2 = p // 2
                tree[p2] = tree[2 * p2] + tree[2 * p2 + 1]
                p = p2

        def search(x):
            p = 1
            if tree[p] == 0: return 0
            for i in reversed(range(MAXB)):
                b = (x >> i) & 0x1
                p2 = 2 * p + (1 - b)
                if not tree[p2]:
                    p2 = 2 * p + b
                p = p2
            assert (tree[p])
            return (p - N) ^ x

        j, k = 0, 0
        ans = 0
        for i in range(len(nums)):
            while j < i:
                update(nums[j], 0)
                j += 1
            while k < len(nums) and nums[k] <= 2 * nums[i]:
                update(nums[k], 1)
                k += 1
            r = search(nums[i])
            ans = max(ans, r)
        return ans