目录
显示
题目链接
https://www.luogu.org/problem/P1494
题解
莫队板子题。
我们先将询问套路性地排序,在两个区间转移的时候暴力统计答案即可。
别忘了特判 \(l=r\) 的情况。
#include <cmath> #include <iostream> #include <algorithm> using namespace std; struct query { int l,r,bl,br,id; }q[50005]; long long a[50005],t[50005],ans1[50005],ans2[50005],num1; bool cmp(const query&a,const query&b) { return a.bl<b.bl||(a.bl==b.bl&&a.br<b.br); } long long gcd(long long x,long long y) { return y==0?x:gcd(y,x%y); } void add(int x) { num1+=t[x]*2; t[x]++; } void del(int x) { t[x]--; num1-=t[x]*2; } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; int siz=sqrt(n); for(int i=1;i<=m;i++) { cin>>q[i].l>>q[i].r; q[i].bl=(q[i].l-1)/siz+1; q[i].br=(q[i].r-1)/siz+1; q[i].id=i; } sort(q+1,q+m+1,cmp); int l=1,r=0; for(int i=1;i<=m;i++) { long long ql=q[i].l,qr=q[i].r; while(l<ql) { del(a[l]); l++; } while(l>ql) { l--; add(a[l]); } while(r<qr) { r++; add(a[r]); } while(r>qr) { del(a[r]); r--; } if(ql==qr) ans1[q[i].id]=0,ans2[q[i].id]=1; else { int tmp=gcd(num1,(qr-ql+1)*(qr-ql)); ans1[q[i].id]=num1/tmp; ans2[q[i].id]=(qr-ql+1)*(qr-ql)/tmp; } } for(int i=1;i<=m;i++) cout<<ans1[i]<<'/'<<ans2[i]<<endl; return 0; }