【题目】
定义数组的异或和的概念:
数组中所有的数异或起来,得到的结果叫做数组的异或和,
比如数组{ 3,2,1 }的异或和是,3 ^ 2 ^ 1 = 0
给定一个数组arr,你可以任意把arr分成很多不相容的子数组,你的目的是:
分出来的子数组中,异或和为0的子数组最多。
请返回:分出来的子数组中,异或和为0的子数组最多是多少?
【题解】
异或运算性质:
满足交换律和结合律且 0 ^ m = m
DP,假设数组最后一个数的下标是i,并且数组存在一个最优划分,使得划分的子数组个数最多,
那么i有两种情况,
第一,i所在的划分区间异或为0;
第二,i所在的划分区间,异或不为0。
对于第一种情况dp[i] = dp[i - 1]的,
对于第二种情况,假设i的最优划分区间是[k, i],0到i的连续异或为sum,之要求出一个最大的下标k - 1,使得0到k - 1的异或也为sum就行了
【代码】
1 #pragma once 2 #include <iostream> 3 #include <map> 4 #include <vector> 5 6 using namespace std; 7 8 int XORSumArray(vector<int>v) 9 { 10 int res = 0; 11 int Xor = 0;//异或和 12 vector<int>dp(v.size(), 0); 13 map<int, int>m;// key表示异或结果,value表示出现下标 14 m[0] = -1;//最初异或和为0的位置为-1 15 for (int i = 0; i < v.size(); ++i) 16 { 17 Xor ^= v[i]; 18 if (m.find(Xor) != m.end())//存在 19 dp[i] = m[Xor] == -1 ? 1 : (dp[m[Xor]] + 1); 20 if (i > 0) 21 dp[i] = dp[i - 1] > dp[i] ? dp[i - 1] : dp[i]; 22 m[Xor] = i; 23 res = res > dp[i] ? res : dp[i]; 24 } 25 return res; 26 } 27 28 void Test() 29 { 30 vector<int>v; 31 v = {1,2,3,1,2,3,1,2,3}; 32 cout << XORSumArray(v) << endl; 33 v = {1,2,3,4,5,6,7,8,9,10}; 34 cout << XORSumArray(v) << endl; 35 v = { 1,2,3,4,5,6,7,8,9,10,11 }; 36 cout << XORSumArray(v) << endl; 37 }