题目背景
Ysuperman 模板测试的数据结构题。
符卡可以是人名也可以是队名。
题目描述
符卡有一个长度为 nnn 的整数数组 aaa,符卡认为一个区间 [l,r][l,r][l,r] 是灵异区间当且仅当 ⨁i=lrai=0\bigoplus_{i=l}^ra_i=0⨁i=lrai=0,或者说这个区间内所有数字异或起来刚好等于 000。
符卡有特殊的魔法,可以把任意一个灵异区间翻转。具体来说,如果 [l,r][l,r][l,r] 区间是灵异区间,那么符卡就可以对这个区间使用魔法,整个数组就会变成 a1,a2,…,al−1,ar,ar−1,…,al,ar+1,ar+2…,ana_1,a_2,\dots,a_{l-1},a_r,a_{r-1},\dots,a_l,a_{r+1},a_{r+2}\dots,a_na1,a2,…,al−1,ar,ar−1,…,al,ar+1,ar+2…,an。
现在符卡可以使用任意次数的魔法,符卡希望最后得到的数组的灵异区间数量能够尽可能多,你能告诉她最后最多有多少个灵异区间吗?
输入格式
第一行一个正整数 nnn,表示数组长度。
第二行 nnn 个非负整数 a1,a2,…,ana_1,a_2,\dots,a_na1,a2,…,an 表示整个数组。
输出格式
输出一行一个整数,表示符卡使用任意次魔法后灵异区间最多有多少个。
样例 #1
样例输入 #1
3
1 1 1
样例输出 #1
2
样例 #2
样例输入 #2
4
3 1 2 3
样例输出 #2
2
提示
样例 1 解释
无论符卡发动多少次魔法,数组都是 1,1,11,1,11,1,1,所以发不发动魔法都没有任何关系。灵异区间永远都是 [1,2],[2,3][1,2],[2,3][1,2],[2,3] 两个。
样例 2 解释
这里给出可能的一种魔法发动方法。
选择灵异区间 [1,3][1,3][1,3] 发动魔法,得到的新数组是 2,1,3,32,1,3,32,1,3,3,这个数组共有两个灵异区间,分别是 [1,3][1,3][1,3] 和 [3,4][3,4][3,4]。
可以证明答案无法超过 222。
数据范围
对于前 20%20\%20% 的数据,保证 n≤10n\le 10n≤10。
对于前 40%40\%40% 的数据,保证 n≤2000n\le 2000n≤2000。
另有 10%10\%10% 的数据,保证 aia_iai 全部相等。
另有 10%10\%10% 的数据,保证 aia_iai 只有两种可能的取值。
另有 10%10\%10% 的数据,保证 0≤ai<2100\le a_i<2^{10}0≤ai<210。
对于 100%100\%100% 的数据,满足 1≤n≤1051\le n\le 10^51≤n≤105,0≤ai<2200\le a_i< 2^{20}0≤ai<220。
彩蛋
灵异区间的名字其实是“零异(或)区间”的谐音。
这题是个经典前缀和,但处理完要异或,而且要开long long。
具体思路写代码里,这里就不做详解。
Code
#include <bits/stdc++.h>
using namespace std;
long long a[100050],b[100050];
int main(){
long long n,s=0;
map<int,int> c;//数组不够大,直接开map
cin>>n;
c[0]=1;
for(int i=1;i<=n;i++){
cin>>a[i];//输入数字
}
for(int i=1;i<=n;i++){
b[i]=a[i]^b[i-1];//异或
s=s+c[b[i]];//记录答案
c[b[i]]++;
}
cout<<s;//输出
return 0;
}
385

被折叠的 条评论
为什么被折叠?



