技巧:
累加二进制位上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)) } }