题目大意:给一列数,问有多少区间,出现的数字都出现了奇数次。
题解:给每种数字赋一个随机权值。
那么
[
L
,
R
]
[L,R]
[L,R]合法,当且仅当,
S
R
x
o
r
S
L
−
1
=
Q
L
S_{R}\ \mathrm{xor}\ S_{L-1}=Q_{L}
SR xor SL−1=QL,其中
Q
L
Q_L
QL是类似扫描线维护区间不同数字的那个感觉,就是每次你要把
(
p
r
e
R
,
R
]
(pre_R,R]
(preR,R]的位置的
Q
L
Q_L
QL全部异或上
r
a
n
d
o
m
_
v
a
l
u
e
R
random\_value_R
random_valueR,因此问题就是区间异或,询问区间某个数字出现次数。这个显然分块然后unordered_map存一下即可。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x<<" "
//#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct Rand{
ull x;Rand() { x=1; }
inline ull operator()() { return ((((x^=998244353)+=19260817)*=1000000007)+=rand())^=rand(); }
}rnd;
typedef unordered_map<ull,int> umap;
const int N=30010,BC=N,SZ=N,V=1000010;
int bel[N],L[BC],R[BC],a[N],las[V],pre[N],sz,bc;
umap um[BC];ull blcv[BC],sp[N],key[N],s[N];
inline int upd(int l,int r,ull v)
{
int bl=bel[l],br=bel[r];
if(bl==br) rep(i,l,r) um[bl][sp[i]]--,um[bl][sp[i]^=v]++;
else{
rep(i,bl+1,br-1) blcv[i]^=v;
rep(i,l,R[bl]) um[bl][sp[i]]--,um[bl][sp[i]^=v]++;
rep(i,L[br],r) um[br][sp[i]]--,um[br][sp[i]^=v]++;
}
return 0;
}
inline int query(int p,ull v)
{
int ans=0;
rep(i,1,bel[p]-1) if(um[i].count(v^blcv[i])) ans+=um[i][v^blcv[i]];
rep(i,L[bel[p]],p) ans+=(v==(sp[i]^blcv[bel[p]]));return ans;
}
int main()
{
// freopen("data.in","r",stdin),freopen("std.out","w",stdout);
int n=inn();rep(i,1,n) a[i]=inn();
rep(i,1,n)
{
if(!las[a[i]]) key[i]=rnd();
else key[i]=key[las[a[i]]];
pre[i]=las[a[i]],las[a[i]]=i;
}
rep(i,1,n) s[i]=s[i-1]^key[i],sp[i]=s[i-1];
sz=(int)sqrt(n/2+1),bc=(n-1)/sz+1;//if(!sz) sz=1,bc=n;
rep(i,1,bc) { L[i]=(i-1)*sz+1,R[i]=min(i*sz,n);rep(j,L[i],R[i]) bel[j]=i; }
lint ans=0;
rep(i,1,n) um[bel[i]][sp[i]]++,upd(pre[i]+1,i,key[i]),ans+=query(i,s[i]);
return !printf("%lld\n",ans);
}