每种颜色单独做
枚举右端点,另 pi 表示前缀 i 中,当前颜色的个数, qi 表示前缀 i 中不是当前颜色的个数
那么答案就要加上满足 pr−qr>pl−1−ql−1 的 l 的个数
这个东西线段树大力搞吧……
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N=1000010;
int n,a[N];
vector<int> b[N];
ll tag[N<<2],tot[N<<2],sum[N<<2],L[N<<2],R[N<<2];
int c[N<<2];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
void rebuild(int g,int l,int r){
L[g]=l; R[g]=r; tot[g]=tag[g]=sum[g]=0;
if(l==r) return ;
int mid=l+r>>1;
rebuild(g<<1,l,mid); rebuild(g<<1|1,mid+1,r);
}
inline void add(int g,int x){
tag[g]+=x; sum[g]+=(R[g]-L[g]+1)*x; tot[g]+=(2*n+2-L[g]-R[g])*(R[g]-L[g]+1)/2*x;
}
inline void clear(int g){
sum[g]=tot[g]=tag[g]=0; c[g]=1;
}
inline void Push(int g){
if(c[g])
clear(g<<1),clear(g<<1|1),c[g]=0;
if(tag[g])
add(g<<1,tag[g]),add(g<<1|1,tag[g]),tag[g]=0;
}
inline void Up(int g){
tot[g]=tot[g<<1]+tot[g<<1|1];
sum[g]=sum[g<<1]+sum[g<<1|1];
}
void Add(int g,int l,int r,int L,int R){
if(L==l && r==R) return add(g,1);
int mid=L+R>>1; Push(g);
if(r<=mid) Add(g<<1,l,r,L,mid);
else if(l>mid) Add(g<<1|1,l,r,mid+1,R);
else Add(g<<1,l,mid,L,mid),Add(g<<1|1,mid+1,r,mid+1,R);
Up(g);
}
typedef pair PAR;
inline PAR operator +(PAR a,PAR b){
return PAR(a.first+b.first,a.second+b.second);
}
PAR Query(int g,int l,int r,int L,int R){
if(l>r) return PAR(0,0);
if(l==L && r==R) return PAR(tot[g],sum[g]);
int mid=L+R>>1; Push(g);
if(r<=mid) return Query(g<<1,l,r,L,mid);
else if(l>mid) return Query(g<<1|1,l,r,mid+1,R);
else return Query(g<<1,l,mid,L,mid)+Query(g<<1|1,mid+1,r,mid+1,R);
}
int main(){
freopen("6253.in","r",stdin);
freopen("6253.out","w",stdout);
read(n); int tp; read(tp);
for(int i=1;i<=n;i++)
read(a[i]),b[a[i]].push_back(i);
ll ans=0;
rebuild(1,-n,n);
for(int x=0;xif(!b[x].size()) continue;
clear(1); Add(1,-b[x][0]+1,0,-n,n);
b[x].push_back(n+1);
int pre=-b[x][0]+1;
for(int i=0;i1;i++){
pre++; int delt=b[x][i+1]-b[x][i]-1;
ans+=Query(1,-n,pre-delt-1,-n,n).second*(delt+1);
PAR cur=Query(1,pre-delt,pre-1,-n,n);
ans+=cur.first-cur.second*(n-pre+1);
Add(1,pre-delt,pre,-n,n);
pre-=delt;
}
}
cout<return 0;
}