利用异或前缀和,如果两个前缀的异或值相同,那么中间这一段连续的序列就满足条件,用map记录一下前缀和出现的次数,具体计数方法见代码。
颜色只有20中,一个int型就可以记录所有状态。
#include <iostream>
#include <cmath>
#include <map>
#include <set>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <queue>
#include <vector>
#define IO \
ios::sync_with_stdio(false); \
// cout.tie(0);
#define lson(x) node << 1, start, mid
#define rson(x) node << 1 | 1, mid + 1, end
using namespace std;
// int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> P;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
const int maxm = 1e4 + 10;
const LL mod = 1e9 + 7;
const double eps = 1e-8;
const double pi = acos(-1);
int dis[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};
// int m[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int a[maxn], sum[maxn];
int n;
map<int, int> mp;
int main()
{
#ifdef WXY
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
IO;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] ^ (1 << a[i]);
}
mp[0] = 1;
LL ans = 0;
for (int i = 1; i <= n; i++)
{
ans = ans + 1LL * mp[sum[i]];
++mp[sum[i]];
}
cout << ans;
return 0;
}