莫队算法
Posted z1j1n1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了莫队算法相关的知识,希望对你有一定的参考价值。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; long long lm,rm; long long c[50001],a[50001]; long long t1,t2; long long ans; struct data{ long long l,r,key1,num; }q[50001]; struct str{ long long s,m; }an[50001]; bool comp(const data &a, const data &b){ if (a.key1<b.key1) return(1); if (a.key1>b.key1) return(0); if (a.r<b.r) return(1); return(0); } long long gcd(long long a,long long b){ if (a%b==0) return(b);else return(gcd(b,a%b)); } void movel(long long targ){ if (lm<targ) for (;lm<targ;){ ans=ans-c[a[lm]]*(c[a[lm]]-1)+(c[a[lm]]-1)*(c[a[lm]]-2); c[a[lm]]--; lm++; } if (lm>targ) for (;lm>targ;){ lm--; ans=ans-c[a[lm]]*(c[a[lm]]-1)+c[a[lm]]*(c[a[lm]]+1); c[a[lm]]++; } } void mover(long long targ){ if (rm<targ) for (;rm<targ;){ rm++; ans=ans-c[a[rm]]*(c[a[rm]]-1)+(c[a[rm]]+1)*c[a[rm]]; c[a[rm]]++; } if (rm>targ) for (;rm>targ;){ ans=ans-c[a[rm]]*(c[a[rm]]-1)+(c[a[rm]]-1)*(c[a[rm]]-2); c[a[rm]]--; rm--; } } int main(){ long long n,m; scanf("%lld%lld",&n,&m); int siz=int(sqrt(n)); for (long long i=1;i<=n;i++) scanf("%lld",&a[i]); for (long long i=1;i<=m;i++) { scanf("%lld%lld",&q[i].l,&q[i].r); q[i].key1=q[i].l/siz; q[i].num=i; } sort(q+1,q+m+1,comp); lm=1,rm=0; ans=0; for (long long i=1;i<=m;i++){ movel(q[i].l);mover(q[i].r); t1=ans;t2=(rm-lm+1)*(rm-lm); if (t1!=0){ long long gc=gcd(t1,t2); an[q[i].num].s=t1/gc;an[q[i].num].m=t2/gc; } else { an[q[i].num].s=0;an[q[i].num].m=1; } } for (int i=1;i<=m;i++) printf("%lld/%lld\n",an[i].s,an[i].m); }
BZOJ2038 小Z的袜子
以上是关于莫队算法的主要内容,如果未能解决你的问题,请参考以下文章