Tsinsen A1206. 小Z的袜子

  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\n",ans1[i],ans2[i]);
137     return 0;
138 }

 

posted @ 2017-03-28 22:17  BBBob  阅读(197)  评论(0编辑  收藏  举报