[bzoj 2038]莫队算法
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; long long gcd(long long a,long long b) { return a==0?b:gcd(b%a,a); } const int maxn=50005; int block_size; struct Query { int l,r; int id; long long ans,L; bool operator<(const Query &q) const { return (l/block_size<q.l/block_size) || ((l/block_size==q.l/block_size)&&(r<q.r)); } }query[maxn]; int a[maxn]; long long cnt[maxn]; pair<long long,long long> ans[maxn]; int main() { int n,m; scanf("%d%d",&n,&m); block_size=(int)sqrt(n); for (int i=0;i<n;i++) scanf("%d",&a[i]); for (int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); x--; y--; query[i].id=i; query[i].l=x; query[i].r=y; query[i].ans=0; query[i].L=y-x+1; } sort(query,query+m); // for (int i=0;i<m;i++) printf("%d %d\n",query[i].l,query[i].r); if (m>0) { for (int i=query[0].l;i<=query[0].r;i++) { cnt[a[i]]++; } for (int i=0;i<maxn;i++) { query[0].ans+=(cnt[i]-1)*cnt[i]/2; } } for (int i=1;i<m;i++) { query[i].ans=query[i-1].ans; while (query[i-1].r<query[i].r) { query[i-1].r++; int j=a[query[i-1].r]; query[i].ans+=cnt[j]; cnt[j]++; } while (query[i-1].l>query[i].l) { query[i-1].l--; int j=a[query[i-1].l]; query[i].ans+=cnt[j]; cnt[j]++; } while (query[i-1].r>query[i].r) { query[i-1].r--; int j=a[query[i-1].r+1]; cnt[j]--; query[i].ans-=cnt[j]; } while (query[i-1].l<query[i].l) { query[i-1].l++; int j=a[query[i-1].l-1]; cnt[j]--; query[i].ans-=cnt[j]; } } for (int i=0;i<m;i++) { long long fi=query[i].ans; long long se=query[i].L*(query[i].L-1)/2; if (fi==0) se=1; long long g=gcd(fi,se); ans[query[i].id]=make_pair(fi/g,se/g); } for (int i=0;i<m;i++) { printf("%lld/%lld\n",ans[i].first,ans[i].second); } return 0; }