技巧:
累加二进制位上1的数量 ,由于XOR特性,贪心选择每一位上是0还是1。
思路:
由于最后是一个范围查询操作。先想到了前缀和
由于XOR特性( 0 变1 , 1 变 0) 要想区间XOR和最大, 那么X这个数字的每一位选择取决于区间内对应该位上的‘1’数量是否过半。
实现 (有时候会超时不通过 不知道是不是go语言的问题???):
package main
import (
"fmt"
)
// 求区间01串差值 并求出处理策略
func diffRange(arr [][31]int, L, R int) int {
tmp, gap, ans := -1, R-L+1, 0
for i := 0; i < 31; i++ {
tmp = arr[R][i]
if L > 0 {
tmp -= arr[L-1][i]
}
// '1' 的数量过半 那么就要变成0
// '0' 的数量过半 那么就要变成1
if (tmp << 1) < gap {
ans |= 1 << (30 - i)
}
}
return ans
}
func main() {
var n, q int
fmt.Scan(&n)
aSum := make([][31]int, n)
for i := 0; i < n; i++ {
var tmp int
fmt.Scan(&tmp)
// 构建每一位'1'数量的前缀和
for j := 30; j >= 0; j-- {
aSum[i][j] = (tmp >> (30 - j)) & 1
if i > 0 {
aSum[i][j] += aSum[i-1][j]
}
}
}
fmt.Scan(&q)
for i := 0; i < q; i++ {
var L, R int
fmt.Scan(&L, &R)
fmt.Println(diffRange(aSum, L-1, R-1))
}
}

京公网安备 11010502036488号