1310. 子数组异或查询

106 阅读1分钟

**题目: **
leetcode.cn/problems/xo…

算法:
方法一:树状数组
本质上这道题利用了特性 xor(left, right) = xor(1, right) xor xor(1, left - 1),其余的做法就是构造一棵树状数组

func xorQueries(arr []int, queries [][]int) []int {
    n, m := len(arr), len(queries)
    BIT = make([]int, n + 1)
    // 构造BIT
    for i := range arr {
        add(i + 1, arr[i])
    }
    ans := make([]int, m)
    for i := range queries {
        ans[i] = query(queries[i][1] + 1) ^ query(queries[i][0])
    }
    return ans
}

var BIT []int

func query(index int) int {
    ans := 0
    for i := index; i > 0; i = i -lowbit(i) {
        ans = ans ^ BIT[i]
    }
    return ans
}

func lowbit(x int) int{
    return x & -x
}

func add(index, value int) {
    for i := index; i < len(BIT); i = i + lowbit(i) {
        BIT[i] = BIT[i] ^ value
    }
}

方法二:前缀异或

func xorQueries(arr []int, queries [][]int) []int {
    n, m := len(arr), len(queries)
    // 从第1个元素开始,sum的每个元素是index <= i的所有元素异或的结果。
    // 同样有xor(left, right) = sum[1, right] xor sum[1, left - 1]
    sum := make([]int, n + 1)
    for i := range arr {
        sum[i + 1] = sum[i] ^ arr[i]
    }
    ans := make([]int, m)
    for i := range queries {
        ans[i] = sum[queries[i][1] + 1] ^ sum[queries[i][0]]
    }
    return ans
}