bzoj2038: [2009国家集训队]小Z的袜子(hose)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 #define maxn 50005 8 typedef long long ll; 9 ll ans=0,Ans[maxn],Bns[maxn]; 10 int n,m,sum[maxn],a[maxn],block[maxn],temp; 11 struct Tsegment{ 12 int id,l,r; 13 }qs[maxn]; 14 void prepare(){ 15 temp=sqrt(n); 16 for (int i=1;i<=n;i++) block[i]=(i-1)/temp+1; 17 } 18 bool comp(Tsegment x,Tsegment y){ 19 if (block[x.l]==block[y.l]){ 20 if (block[x.l]%2==1) return x.r<y.r; 21 else return x.r>y.r; 22 } 23 return block[x.l]<block[y.l]; 24 } 25 void change(int z,int y){ 26 int x=a[z]; 27 ans-=1LL*sum[x]*(sum[x]-1); 28 sum[x]+=y; 29 ans+=1LL*sum[x]*(sum[x]-1); 30 } 31 ll gcd(ll x,ll y){ 32 if (y==0) return x; 33 return gcd(y,x%y); 34 } 35 void work(){ 36 ans=0; 37 for (int l=1,r=0,i=1;i<=m;i++){ 38 for (;qs[i].l<l;l--) change(l-1,1); 39 for (;qs[i].l>l;l++) change(l,-1); 40 for (;qs[i].r>r;r++) change(r+1,1); 41 for (;qs[i].r<r;r--) change(r,-1); 42 Ans[qs[i].id]=ans; 43 } 44 for (int i=1;i<=m;i++){ 45 if (Ans[i]!=0){ 46 ll x=gcd(Ans[i],Bns[i]); 47 printf("%lld/%lld\n",Ans[i]/x,Bns[i]/x); 48 }else{ 49 printf("0/1\n"); 50 } 51 } 52 } 53 int main(){ 54 scanf("%d%d",&n,&m); 55 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 56 for (int i=1;i<=m;i++) scanf("%d%d",&qs[i].l,&qs[i].r),qs[i].id=i; 57 for (int i=1;i<=m;i++) Bns[i]=1LL*(qs[i].r-qs[i].l+1)*(qs[i].r-qs[i].l); 58 prepare(); 59 sort(qs+1,qs+m+1,comp); 60 work(); 61 return 0; 62 }
题目链接:http://www.lydsy.com/JudgeOnline/problemset.php
题目大意:见题面。
做法:莫队算法。