题面
解析
这就是道莫队模板啊啊!!
因此,似乎并没有什么好讲的。
莫队算法传送门
我们只需要将询问存下来,
离线处理就行了。
还是上代码吧:
#include<bits/stdc++.h> using namespace std; inline int read(){ int sum=0,f=1;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();} return f*sum; } struct node{ int l,r,ans,id; }q[100001]; int n,m,k,l,r,gap,ans=0; int a[100001]/*颜色*/,c[100001]/*颜色的重复次数*/; bool cmp1(node a,node b){ return (a.r/gap==b.r/gap)? a.l<b.l : a.r<b.r; } bool cmp2(node a,node b){ return a.id<b.id; } inline void add(int x){ c[a[x]]++; ans+=2*c[a[x]]-1; } inline void del(int x){ c[a[x]]--; ans-=2*c[a[x]]+1; } int main(){ n=read();m=read();k=read(); gap=n/sqrt(m*2.0/3); for(int i=1;i<=n;i++){ a[i]=read(); } for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(); for(int i=1;i<=m;i++) q[i].id=i; sort(q+1,q+m+1,cmp1); l=1;r=0; for(int i=1;i<=m;i++){ int ql=q[i].l,qr=q[i].r; while(l<ql) del(l),l++; while(l>ql) l--,add(l); while(r>qr) del(r),r--; while(r<qr) r++,add(r); q[i].ans=ans; } sort(q+1,q+m+1,cmp2); for(int i=1;i<=m;i++) printf("%d\n",q[i].ans); return 0; }