传送门:www.lydsy.com/JudgeOnline/problem.php?id=2038
莫队算法,神!
明天就是SDOI2014 Round2 Day1了,希望能过吧,不行还有明年……祝高二大哥们不留遗憾
Code:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=50010; typedef long long lld; lld n,m; lld col[maxn]; lld a[maxn],sqrn; int bel(int x){return (x-1)/sqrn;} lld getint(){ lld res=0,ok=0;char ch; while(1){ ch=getchar(); if(isdigit(ch)){ res*=10;res+=ch-'0';ok=1; }else if(ok)break; }return res; } struct qes{ lld ind,l,r; bool operator < (const qes &a)const{ return bel(l)<bel(a.l)||bel(l)==bel(a.l)&&r<a.r; } }; lld anss[maxn]; lld ans=0; void maintain(int j,int i){ ans-=col[a[j]]*(col[a[j]]-1); col[a[j]]+=i; ans+=col[a[j]]*(col[a[j]]-1); } bool cmp(const qes &a,const qes &b){ return a.ind<b.ind; } lld gcd(lld a,lld b){ while(b){ lld t=a%b; a=b; b=t; }return a; } qes q[maxn]; int main(){ n=getint();m=getint(); sqrn=sqrt(n)+1; for(int i=1;i<=n;i++)a[i]=getint(); for(int i=1;i<=m;i++){ q[i].ind=i;q[i].l=getint();q[i].r=getint(); }sort(q+1,q+1+m); int i=1; while(i<=m){ memset(col,0,sizeof(col)); ans=0; for(int j=q[i].l;j<=q[i].r;j++) maintain(j,1); anss[q[i++].ind]=ans; while(i<=m&&bel(q[i].l)==bel(q[i-1].l)){ for(int j=q[i-1].r+1;j<=q[i].r;j++) maintain(j,1); if(q[i-1].l<q[i].l){ for(int j=q[i-1].l;j<q[i].l;j++) maintain(j,-1); }else{ for(int j=q[i].l;j<q[i-1].l;j++) maintain(j,1); } anss[q[i++].ind]=ans; } } sort(q+1,q+1+m,cmp); for(int i=1;i<=m;i++){ lld k=(q[i].r-q[i].l+1)*(q[i].r-q[i].l);//这里由于原来用intWA了一次 if(k==0||anss[i]==0){ puts("0/1");continue; } lld d=gcd(k,anss[i]); printf("%lld/%lld\n",anss[i]/d,k/d); } return 0; }