思路
简单的莫队,开个桶记录下颜色出现次数即可
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
int sum,color[200200],L,R,n,m,a[200200],belong[200200],sz,ans[200200],b[200200],tx;
struct Query{
int l,r,id;
bool operator < (const Query &b) const{
return belong[l]==belong[b.l]?r<b.r:belong[l]<belong[b.l];
}
}Q[200200];
void init(void){
int sz=sqrt(n);
for(int i=1;i<=n;i++)
belong[i]=(i-1)/sz+1;
}
void moveL(int opt){
if(opt==1){
sum-=color[a[L]]*color[a[L]];
color[a[L]]--;
sum+=color[a[L]]*color[a[L]];
L++;
}
else{
L--;
sum-=color[a[L]]*color[a[L]];
color[a[L]]++;
sum+=color[a[L]]*color[a[L]];
}
// printf("L=%d sum=%d
",L,sum);
}
void moveR(int opt){
if(opt==1){
R++;
sum-=color[a[R]]*color[a[R]];
color[a[R]]++;
sum+=color[a[R]]*color[a[R]];
}
else{
sum-=color[a[R]]*color[a[R]];
color[a[R]]--;
sum+=color[a[R]]*color[a[R]];
R--;
}
// printf("R=%d sum=%d
",R,sum);
}
int main(){
int k;
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
tx=unique(b+1,b+n+1)-(b+1);
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+tx+1,a[i])-b;
// for(int i=1;i<=n;i++)
// printf("%d ",a[i]);
for(int i=1;i<=m;i++){
scanf("%d %d",&Q[i].l,&Q[i].r);
Q[i].id=i;
}
init();
sort(Q+1,Q+m+1);
L=1;
R=sum=0;
for(int i=1;i<=m;i++){
while(L>Q[i].l)
moveL(-1);
while(R<Q[i].r)
moveR(1);
while(L<Q[i].l)
moveL(1);
while(R>Q[i].r)
moveR(-1);
ans[Q[i].id]=sum;
}
for(int i=1;i<=m;i++){
printf("%d
",ans[i]);
}
return 0;
}