题解 P2709 【小B的询问】
这题其实是一个非常模板的无修改的莫队。
说下思路:
我们可以拿一个mp数组记录在一个区间内各种颜色出现的个数,然后就是跑一遍普通莫队。(加减时要注意平方)。
l记得要从1开始。
#include<bits/stdc++.h>
using namespace std;
struct data
{
int x,y,id,ans;
}a[50010];
int gg,n,m,k,c[50010],b[50010],mp[50010],l=1,r,ans;
bool operator < (data a,data b)
{
if(c[a.x]==c[b.x])
{
return a.y<b.y;
}
return a.x<b.x;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
gg=pow(n,0.54);//据说是最快的分块方式
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
c[i]=(i-1)/gg+1;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].id=i;
}
sort(a+1,a+m+1);
for(int i=1;i<=m;i++)//处理(平方)
{
while(l<a[i].x)
{
ans-=mp[b[l]]*mp[b[l]];
mp[b[l]]--;
ans+=mp[b[l]]*mp[b[l]];
l++;
}
while(l>a[i].x)
{
l--;
ans-=mp[b[l]]*mp[b[l]];
mp[b[l]]++;
ans+=mp[b[l]]*mp[b[l]];
}
while(r>a[i].y)
{
ans-=mp[b[r]]*mp[b[r]];
mp[b[r]]--;
ans+=mp[b[r]]*mp[b[r]];
r--;
}
while(r<a[i].y)
{
r++;
ans-=mp[b[r]]*mp[b[r]];
mp[b[r]]++;
ans+=mp[b[r]]*mp[b[r]];
}
a[a[i].id].ans=ans;//按id来给答案
}
for(int i=1;i<=m;i++)//输出
{
printf("%d\n",a[i].ans);
}
return 0;
}