在loj上看到的题,跟CF77F差不多
但是这不是一个线段,而是一些数字,就不能用同样的方法hash,问了大佬Manchery,恰好他一周前做过……传送门
不过loj上数据更强吧…我Hash打错调了一晚上……
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#define fi first
#define se second
using namespace std;
const int N=200010,P=100003;
typedef unsigned long long ull;
typedef pair<ull,int> par;
int n,block;
int a[N],lst[N*5];
ull val[N],Hash[N*5];
inline int Hash_(ull x){
return x%P;
}
struct Hst{
ull tag;
Hst(){ tag=cnt=bnt=0; }
int H[P+5],nxt[550],bin[550],bnt,cnt;
par key[550];
void insert(ull x){
int u=Hash_(x);
for(int i=H[u];i;i=nxt[i])
if(key[i].fi==x){ key[i].se++; return ; }
int cur=bnt?bin[bnt--]:++cnt;
key[cur]=par(x,1); nxt[cur]=H[u]; H[u]=cur;
}
void erase(ull x){
int u=Hash_(x),v=0,l=0;
for(int i=H[u];i;l=i,i=nxt[i])
if(key[i].fi==x) { v=i; break; }
if(!v) return ; --key[v].se;
if(key[v].se) return ;
if(l) nxt[l]=nxt[v]; else H[u]=nxt[v];
bin[++bnt]=v;
}
int count(ull x){
x^=tag; int u=Hash_(x);
for(int i=H[u];i;i=nxt[i])
if(key[i].fi==x) return key[i].se;
return 0;
}
}T[550];
void Modify(int l,int r,ull flg){
int L=l/block,R=r/block;
if(L==R){
for(int i=l;i<=r;i++)
T[L].erase(val[i]),T[L].insert(val[i]^=flg);
return ;
}
for(int i=L+1;i<R;i++) T[i].tag^=flg;
for(int i=l;i<(L+1)*block;i++)
T[L].erase(val[i]),T[L].insert(val[i]^=flg);
for(int i=R*block;i<=r;i++)
T[R].erase(val[i]),T[R].insert(val[i]^=flg);
}
int Query(int r,ull tar){
int ret=0,R=r/block;
for(int i=0;i<R;i++)
ret+=T[i].count(tar);
for(int i=R*block;i<=r;i++)
if((val[i]^T[R].tag)==tar) ret++;
return ret;
}
int main(){
scanf("%d",&n); block=sqrt(n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(!Hash[a[i]]) Hash[a[i]]=1LL*rand()*rand()*rand();
}
T[0].insert(0); val[0]=0;
long long ans=0; ull pre=0;
for(int i=1;i<=n;i++){
val[i]=(pre^=Hash[a[i]]);
T[i/block].insert(val[i]);
Modify(lst[a[i]],i-1,Hash[a[i]]); lst[a[i]]=i;
ans+=Query(i-1,pre);
}
cout<<ans<<endl;
return 0;
}