[cf86D]Powerful array

Description

给定一个长度为n的数组,t次查询,求\(\sum_{i=l}^{r}a_i*s_{a_i}^2\)。其中,\(s_k\)\(k\)在区间\([l,r]\)出现的次数。

Solution

莫队裸题。

include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N=200005,K=1000005;
struct query{
int l,r,n;
}q[N];
int a[N],s[K],f[N],n,m,t;
ll ans[N];
bool cmp(query a,query b){
if(f[a.l]!=f[b.l]) return f[a.l]<f[b.l];
return a.r<b.r;
}
ll add(int i){
++s[a[i]];
return 1lla[i]((s[a[i]]<<1)-1);
}
ll remove(int i){
--s[a[i]];
return 1lla[i](s[a[i]]<<1|1);
}
int main(){
scanf("%d%d",&n,&t);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=t;++i){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].n=i;
}
m=sqrt(n);
for(int i=1,k=1;i<=n;++k)
for(int j=1;i<=n&&j<=m;++i,++j)
f[i]=k;
sort(q+1,q+1+t,cmp);
int l=1,r=1;
ll tmp=1ll*a[1];
++s[a[1]];
for(int i=1;i<=t;++i){
while(r<q[i].r){
++r;tmp+=add(r);
}
while(r>q[i].r){
tmp-=remove(r);--r;
}
while(l>q[i].l){
--l;tmp+=add(l);
}
while(l<q[i].l){
tmp-=remove(l);++l;
}
ans[q[i].n]=tmp;
}
for(int i=1;i<=t;++i)
printf("%lld\n",ans[i]);
return 0;
}

posted @ 2022-01-06 21:45  Aireen_Ye  阅读(113)  评论(0)    收藏  举报
底部 顶部 留言板 归档 标签
Der Erfolg kommt nicht zu dir, du musst auf den Erfolg zugehen.