如果一段连续子数组异或和为0 边界两端的异或和必然相等
如:arr[i~j ] 异或和为为0 则至少说明 【-i)异或和 等于 【0-j) 异或和
我们假设dp[i] 标示 0-i 的所求,则我们按照异或和维度存储下来一份映射关系
mapTmp[eor] = i eor => i
dp[i] = dp[map[eor]]+1
dp[0] = arr[0] == 0?1:0
最后我们是求最大,dp[i] = max(dp[i-1],dp[i])
package main
import (
"fmt"
"os"
"bufio"
"strconv"
)
func main(){
var n int
fmt.Scanf("%d",&n)
arr := make([]int,n)
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
for i:=0;i<n;i++{
scanner.Scan()
arr[i],_ = strconv.Atoi(scanner.Text())
}
helper(arr,n)
return
}
func helper(arr []int, n int){
dp := make([]int,n)
mapTmp := make(map[int]int)
mapTmp[0] = -1
//mapTmp[arr[0]] = 0
eor := 0
if arr[0] ==0 {
dp[0] = 1
}
for i:=0;i<n;i++{
eor ^= arr[i]
//发现再次出现
if val,ok := mapTmp[eor]; ok{
if val == -1 {
//说明上次出现的位置在首位
dp[i] = 1
}else{
//说明当前值应该基于上一次出现的值的位置 +1
dp[i] = dp[val] +1
}
}
mapTmp[eor] = i
//与前一个值相比,得到最大值
if i!=0 && dp[i] < dp[i-1]{
dp[i] = dp[i-1]
}
}
fmt.Println(dp[n-1])
}


京公网安备 11010502036488号