题目
这道题是莫队算法的模板题。只要求出从状态[L,R]到[L+1,R],[L,R+1],[L-1,R],
[L,R-1]的状态转移的情况,再套模板就可以了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for(register int i=l;i<=r;i++)
#define per(i,r,l) for(register int i=r;i>=l;i--)
using namespace std;
const int maxn=50010;
int read()
{
int res=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
res=res*10+ch-'0';
ch=getchar();
}
return res*f;
}
struct node
{
int l;
int r;
int kuai;
int bian;
}xun[maxn];
int cmp(node a,node b)
{
if(a.kuai<b.kuai) return 1;
if(a.kuai==b.kuai&&a.r<b.r) return 1;
else return 0;
}
int a[maxn],cnt[maxn],m,n,k,t,ans[maxn],answ;
int main()
{
n=read();m=read();k=read();
rep(i,1,n) a[i]=read();
t=sqrt(n);
rep(i,1,m) {xun[i].bian=i;xun[i].l=read();xun[i].r=read();xun[i].kuai=xun[i].l/t;}
sort(xun+1,xun+m+1,cmp);
rep(i,xun[1].l,xun[1].r) {answ+=2*cnt[a[i]]+1;cnt[a[i]]++;}
ans[xun[1].bian]=answ;
rep(i,2,m)
{
while(xun[i].l>xun[i-1].l)
{ answ=answ-2*cnt[a[xun[i-1].l]]+1;cnt[a[xun[i-1].l]]--;xun[i-1].l++;}
while(xun[i].l<xun[i-1].l)
{ xun[i-1].l--;answ=answ+2*cnt[a[xun[i-1].l]]+1;cnt[a[xun[i-1].l]]++;}
while(xun[i].r>xun[i-1].r)
{ xun[i-1].r++;answ=answ+2*cnt[a[xun[i-1].r]]+1;cnt[a[xun[i-1].r]]++;}
while(xun[i].r<xun[i-1].r)
{ answ=answ-2*cnt[a[xun[i-1].r]]+1;cnt[a[xun[i-1].r]]--;xun[i-1].r--;}
ans[xun[i].bian]=answ;
}
rep(i,1,m) printf("%d\n",ans[i]);
return 0;
}