BZOJ 2038 [2009国家集训队]小Z的袜子(hose)
莫队算法第一题。
强制类型转换没写,WA了好久才发现......
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=50000+10; int n,m; struct X { int l,r,id; long long ans1,ans2; } s[maxn]; int a[maxn]; int pos[maxn]; long long cnt[maxn]; long long Ans; int L,R; bool cmp(const X&a,const X&b) { if(pos[a.l]==pos[b.l]) return a.r<b.r; return a.l<b.l; } bool cmp1(const X&a,const X&b) { return a.id<b.id; } long long gcd(long long a,long long b) { if(b==0) return a; return gcd(b,a%b); } int main() { scanf("%d%d",&n,&m); int sz=(int)sqrt(1.0*n); memset(cnt,0,sizeof cnt); Ans=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); pos[i]=i/sz; } for(int i=1; i<=m; i++) { scanf("%d%d",&s[i].l,&s[i].r); s[i].id=i; } sort(s+1,s+m+1,cmp); for(int i=s[1].l; i<=s[1].r; i++) { Ans=Ans+cnt[a[i]]; cnt[a[i]]++; } L=s[1].l,R=s[1].r; s[1].ans1=2*Ans; s[1].ans2=(long long)(s[1].r-s[1].l+1)*(long long)(s[1].r-s[1].l); long long tmp=gcd(s[1].ans1,s[1].ans2); s[1].ans1/=tmp; s[1].ans2/=tmp; for(int i=2; i<=m; i++) { while(L<s[i].l) { cnt[a[L]]--; Ans=Ans-cnt[a[L]]; L++; } while(L>s[i].l) { L--; Ans=Ans+cnt[a[L]]; cnt[a[L]]++; } while(R<s[i].r) { R++; Ans=Ans+cnt[a[R]]; cnt[a[R]]++; } while(R>s[i].r) { cnt[a[R]]--; Ans=Ans-cnt[a[R]]; R--; } s[i].ans1=2*Ans; s[i].ans2=(long long)(s[i].r-s[i].l+1)*(long long)(s[i].r-s[i].l); long long tmp=gcd(s[i].ans1,s[i].ans2); s[i].ans1/=tmp; s[i].ans2/=tmp; } sort(s+1,s+m+1,cmp1); for(int i=1; i<=m; i++) printf("%lld/%lld\n",s[i].ans1,s[i].ans2); return 0; }