思路:
因为是求出现次数为偶数的子段,且颜色最多只有20种,因此可以用二进制中对应1左移的位数来表示该数出现的次数是偶数次还是奇数次,可以考虑用异或前缀和来实施此方案。接着从前往后维护偶数次颜色出现的次数,以后的每一个偶数次颜色都能以之前出现过的偶数次颜色作为起点构成新的一组合法子序列。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 998244353;
ll a[1000010];
ll prefix[1000010];
map<ll,int>vis;
int main()
{
int n;
cin>>n;
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
prefix[i] = prefix[i-1]^(1<<a[i]);
}
ll ans = 0;
vis[0] = 1;
for(int i = 1; i <= n; i++)
{
ans += vis[prefix[i]];
vis[prefix[i]]+=1;
}
cout<<ans<<endl;
}