依旧莫队板子题
处理平方的时候可以用加减
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
struct nico
{
int l,r,t;
}ask[50005];
int pos[50005],n,m,k,i,num[50005],x,dl,dr,ans[50005],exist[50005],sum;
int comp(nico a,nico b)
{
if(pos[a.l]<pos[b.l]) return 1;
if(pos[a.l]==pos[b.l]&&a.r<b.r) return 1;
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].t=i;
}
x=sqrt(n);
for(i=1;i<=n;i++)
{
if(i%x==0) pos[i]=i/x;
else pos[i]=(i/x)+1;
}
sort(ask+1,ask+m+1,comp);
dl=ask[1].l;
dr=ask[1].l-1;
for(i=1;i<=m;i++)
{
while(dl<ask[i].l)
{
sum=sum-2*exist[num[dl]]+1;
exist[num[dl]]--;
dl++;
}
while(dl>ask[i].l)
{
dl--;
sum=sum+2*exist[num[dl]]+1;
exist[num[dl]]++;
}
while(dr<ask[i].r)
{
dr++;
sum=sum+2*exist[num[dr]]+1;
exist[num[dr]]++;
}
while(dr>ask[i].r)
{
sum=sum-2*exist[num[dr]]+1;
exist[num[dr]]--;
dr--;
}
ans[ask[i].t]=sum;
}
for(i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}