前缀异或建模。
设前缀异或 p[i] = a1 xor a2 xor … xor ai
(p[0]=0
)。把数组划分为若干连续子段,对应的是选取分割点 0=i0<i1<…<im=n
,第 k
段的异或值为
s_k = p[ik] xor p[ik-1]
。因此问题化为:在前缀序列 p[0..n]
上选点,使相邻点的“异或差”序列 s1..sm
构成**驼峰(交替上升/下降)**序列,且段数 m
最大。
值域仅 0..255 的关键性质。
因为 ai∈[0,255]
,任意前缀异或 p[i]
也在 0..255
。这使得可以用“值压缩 DP”,在每个前缀值上聚合最优状态,从而把状态数量限制在常数级(256)。
状态设计(仅记录“上/下”最后一跳)。
给定一个长度为 n 的整数数组 {a1,a2,...,an},其中每个元素 ai 的取值范围为 0≦ai≦255 ;
你需要将该数组划分为若干个互不相交的非空连续子段,这些子段按照在原数组中的顺序排列后,其按位异或 (xor) 结果必须构成一个驼峰序列;
求最多可以划分出多少个这样的子段。
驼峰序列:对于一个序列 {b1,b2,...,bm} 如果其为驼峰序列,那么対于仼意的 1<i<m 都有 bi−1<bi>bi+1 或者 bi−1>bi<bi+1。
每个测试文件均包含多组测试数据。
第一行输入一个整数 t(1≦t≦1000) ,表示测试用例的组数:
此后 t 组测试数据描述如下:
第一行输入一个整数 n(1≦n≦2×105) ,表示数组长度;
第二行输入 n 个整数 a1,a2,…,an(0≦ai≦255),表示数组元素;
除此之外,保证所有测试用例的 n 之和不超过 2×105 。
对于每组测试数据,输出一个整数,表示最大可划分出的满足条件的子段数量。
输入
3
6
1 2 3 0 1 3
4
0 0 0 0
1
85
输出
3
2
1
说明
在第一组数据中,数组 {1,2,3,0,1,3} 可以划分为 {1},{2},{3,0,1,3},按位异或结果为 1,2,1,是驼峰序列。
在第二组数据中,数组 {0,0,0,0} 可以划分为 {0,0},{0,0} ,对于任意的 1<i<m 均满足条件(因为找不到满足 1<i<m 的 i ) 。