上一道题的双倍经验。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 50050 using namespace std; long long n,m,k,col[maxn],cnt[maxn],ret=0,pos[maxn],block; struct query { long long l,r,id,ans; }p[maxn]; bool cmp1(query x,query y) { if (pos[x.l]!=pos[y.l]) return pos[x.l]<pos[y.l]; return x.r<y.r; } bool cmp2(query x,query y) { return x.id<y.id; } long long gcd(long long x,long long y) { if (y==0) return x; return gcd(y,x%y); } void modify(long long x,long long val) { ret-=cnt[col[x]]*cnt[col[x]]; cnt[col[x]]+=val; ret+=cnt[col[x]]*cnt[col[x]]; } int main() { scanf("%lld%lld%lld",&n,&m,&k); for (long long i=1;i<=n;i++) scanf("%lld",&col[i]); for (long long i=1;i<=m;i++) { scanf("%lld%lld",&p[i].l,&p[i].r); p[i].id=i; } block=sqrt(n); for (long long i=1;i<=n;i++) pos[i]=(i-1)/block+1; sort(p+1,p+m+1,cmp1); long long l=1,r=0; for (long long i=1;i<=m;i++) { for (;r<p[i].r;r++) modify(r+1,1); for (;r>p[i].r;r--) modify(r,-1); for (;l<p[i].l;l++) modify(l,-1); for (;l>p[i].l;l--) modify(l-1,1); p[i].ans=ret; } sort(p+1,p+m+1,cmp2); for (long long i=1;i<=m;i++) printf("%lld ",p[i].ans); return 0; }