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 }
View Code

题目链接:http://www.lydsy.com/JudgeOnline/problemset.php

题目大意:见题面。

做法:莫队算法。

posted @ 2016-06-11 17:01  oyzx~  阅读(171)  评论(0编辑  收藏  举报