题目描述
给定一个整型数组arr,其中可能有正有负有零。你可以随意把整个数组切成若干个不相容的子数组,求异或和为0的子数组最多可能有多少个?整数异或和定义:把数组中所有的数异或起来得到的值。
输入描述:
输出包括两行,第一行一个整数,代表数组长度n(1≤n≤106)。第二行有n个整数,代表数组arr(−1e+9≤arri≤1e+9)。
输出描述:
输出一个整数,表示数组切割最多的子数组的个数。
示例1
输入
10 3 2 1 9 0 7 0 2 1 3
输出
4
说明
最优划分:{3,2,1},{9},{0},{7},{0},{2,1,3} 其中{3,2,1},{0},{0},{2,1,3}的异或和为0
备注:
时间复杂度O(n),空间复杂度O(n)。
//dp[i]的定义是如果在arr[0...i]上做分割,异或和为0的子数组最多能有多少个
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> arr(n);
for(int i=0;i<n;i++){
cin>>arr[i];
}
vector<int> dp(n,0);
dp[0]=(arr[0]==0) ? 1 : 0;
unordered_map<int,int> um;
um[0]=-1;
um[arr[0]]=0;
int eor=0;
for(int i=1;i<n;i++){
eor^=arr[i];
if(um.find(eor)!=um.end()){
int preEorIndex=um[eor];
dp[i]=(preEorIndex==-1) ? 1 : dp[preEorIndex]+1;
}
dp[i]=max(dp[i-1],dp[i]);
um[eor]=i;
}
cout<<dp[n-1]<<endl;
return 0;
}