86D:Powerful array
题意简述
给出一个
n
个元素的数列
设
f(i)
为
i
出现的次数
给出
数据范围
1≤n,q≤2∗105
1≤ai≤106
1≤li≤ri≤n
思路
莫队搞一搞..
时间复杂度
O(nn√)
代码
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int n,q,lim;
int seq[200010],cnt[1000010];
long long tot;
long long ans[200010];
struct ask{
int l,r,id;
bool operator < (const ask &n1) const
{
return l/lim==n1.l/lim ? r<n1.r : l/lim<n1.l/lim;
}
}a[200010];
int main()
{
scanf("%d%d",&n,&q);
lim=int(sqrt(n));
for (int i=1;i<=n;i++)
scanf("%d",&seq[i]);
for (int i=1;i<=q;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].id=i;
}
sort(a+1,a+q+1);
int l=a[1].l,r=a[1].l;
cnt[seq[a[1].l]]++;
tot=seq[a[1].l];
for (int i=1;i<=q;i++)
{
while (l<a[i].l)
{
cnt[seq[l]]--;
tot-=seq[l]*(cnt[seq[l]]*2+1);
l++;
}
while (l>a[i].l)
{
l--;
cnt[seq[l]]++;
tot+=seq[l]*(cnt[seq[l]]*2-1);
}
while (r<a[i].r)
{
r++;
cnt[seq[r]]++;
tot+=seq[r]*(cnt[seq[r]]*2-1);
}
while (r>a[i].r)
{
cnt[seq[r]]--;
tot-=seq[r]*(cnt[seq[r]]*2+1);
r--;
}
ans[a[i].id]=tot;
}
for (int i=1;i<=q;i++)
printf("%I64d\n",ans[i]);
return 0;
}