1 /* 2 Tsinsen A1206. 小Z的袜子 3 http://www.tsinsen.com/new/A1206 4 BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 5 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 6 莫队算法 7 */ 8 #include <cstdio> 9 #include <algorithm> 10 #include <cstring> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 //#define test 15 using namespace std; 16 const int Nmax=50005; 17 long long times[Nmax]; 18 long long n,m; 19 long long num[Nmax]; 20 int pos[Nmax]; 21 int l=1,r=0; 22 struct Q 23 { 24 int l,r,id; 25 26 }q[Nmax]; 27 long long Ans; 28 long long ans1[Nmax],ans2[Nmax]; 29 bool cmp(Q a,Q b) 30 { 31 if(pos[a.l]==pos[b.l]) 32 return a.r<b.r; 33 return pos[a.l]<pos[b.l]; 34 } 35 long long gcd(long long a,long long b) 36 { 37 if(b==0LL) 38 return a; 39 return gcd(b,a%b); 40 } 41 void add(int x) 42 { 43 Ans-=times[num[x]]*times[num[x]]; 44 times[num[x]]++; 45 Ans+=times[num[x]]*times[num[x]]; 46 } 47 void del(int x) 48 { 49 Ans-=times[num[x]]*times[num[x]]; 50 times[num[x]]--; 51 Ans+=times[num[x]]*times[num[x]]; 52 } 53 int main() 54 { 55 #ifdef test 56 #endif 57 scanf("%lld%lld",&n,&m); 58 int sz=sqrt(n); 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%lld",&num[i]); 62 pos[i]=i/sz; 63 } 64 for(int i=1;i<=m;i++) 65 { 66 scanf("%d%d",&q[i].l,&q[i].r); 67 q[i].id=i; 68 } 69 sort(q+1,q+1+m,cmp); 70 for(int i=1;i<=m;i++) 71 { 72 if(q[i].l==q[i].r) 73 { 74 ans1[i]=0; 75 ans2[i]=1; 76 continue; 77 } 78 //if(r<q[i].r) 79 //{ 80 //for(int j=r+1;j<=q[i].r;j++) 81 //add(j); 82 //} 83 //else 84 //{ 85 //for(int j=r;j>q[i].r;j--) 86 //del(j); 87 //} 88 //if(l<q[i].l) 89 //{ 90 //for(int j=l;j<q[i].l;j++) 91 //del(j); 92 //} 93 //else 94 //{ 95 //for(int j=l-1;j>=q[i].l;j--) 96 //add(j); 97 //} 98 //l=q[i].l; 99 //r=q[i].r; 100 while(l<q[i].l) 101 { 102 del(l); 103 l++; 104 } 105 while(l>q[i].l) 106 { 107 l--; 108 add(l); 109 } 110 while(r<q[i].r) 111 { 112 r++; 113 add(r); 114 } 115 while(r>q[i].r) 116 { 117 del(r); 118 r--; 119 } 120 ans1[q[i].id]=Ans-(r-l+1LL);//1必须为1LL,否则会wa 121 ans2[q[i].id]=(r-l+1LL)*(r-l);//同上 122 long long c=1LL; 123 if(Ans) 124 { 125 c=gcd(ans1[q[i].id],ans2[q[i].id]); 126 ans1[q[i].id]/=c; 127 ans2[q[i].id]/=c; 128 } 129 else 130 { 131 ans1[q[i].id]=0LL; 132 ans2[q[i].id]=1LL; 133 } 134 } 135 for(int i=1;i<=m;i++) 136 printf("%lld/%lld ",ans1[i],ans2[i]); 137 return 0; 138 }