莫队模板。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 50050 using namespace std; long long n,m,col[maxn],cnt[maxn],ret=0,pos[maxn],block; struct query { long long l,r,id,a,b; }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",&n,&m); 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); if (p[i].l==p[i].r) {p[i].a=0;p[i].b=1;} else { p[i].a=ret-(p[i].r-p[i].l+1); p[i].b=(p[i].r-p[i].l+1)*(p[i].r-p[i].l); long long d=gcd(p[i].a,p[i].b);p[i].a/=d;p[i].b/=d; } } sort(p+1,p+m+1,cmp2); for (long long i=1;i<=m;i++) printf("%lld/%lld ",p[i].a,p[i].b); return 0; }