小Z的袜子

莫队模板题,初学莫队感觉分块真是神奇。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define fst first
 4 #define scd second
 5 #define pb(x) push_back((x))
 6 #define mkp(x,y) make_pair((x),(y)) 
 7 #define ist(x) insert((x))
 8 typedef long long ll;
 9 typedef pair<int ,int > pii;
10 typedef pair<ll ,ll > pll;
11 typedef vector< int > vi;
12 ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
13 ll qPow(ll a,ll b,ll mod){ ll ret=1ll;while(b){ if(b&1) ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret; }
14 
15 int N,M;
16 int chunk;
17 int a[50000+5];
18 int id[50000+5];
19 pii query[50000+5];
20 pll ans[50000+5];
21 int num[50000+5];
22 
23 bool cmp(int i,int j){
24     pii a=query[i],b=query[j];
25     if((a.scd/chunk)!=(b.scd/chunk))return (a.scd/chunk)<(b.scd/chunk);
26     else return a.fst<b.fst;
27 }
28 
29 void solve(){
30     memset(num,0,sizeof(num));
31     int L=1,R=0;
32     ll calcul=0ll;
33     for(int i=1;i<=M;++i){
34         int index=id[i];
35         int Lb=query[index].fst,Rb=query[index].scd;
36         while(L<Lb){
37             calcul-=1ll*num[a[L]]*num[a[L]];
38             num[a[L]]--;
39             calcul+=1ll*num[a[L]]*num[a[L]];
40             L++;
41         }
42         while(L>Lb){
43             L--;
44             calcul-=1ll*num[a[L]]*num[a[L]];
45             num[a[L]]++;
46             calcul+=1ll*num[a[L]]*num[a[L]]; 
47         }
48         while(R<Rb){
49             R++;
50             calcul-=1ll*num[a[R]]*num[a[R]];
51             num[a[R]]++;
52             calcul+=1ll*num[a[R]]*num[a[R]];
53         }
54         while(R>Rb){
55             calcul-=1ll*num[a[R]]*num[a[R]];
56             num[a[R]]--;
57             calcul+=1ll*num[a[R]]*num[a[R]]; 
58             R--;
59         }
60         ll A=calcul-1ll*(Rb-Lb+1);
61         ll B=1ll*(Rb-Lb+1)*(Rb-Lb);
62         ll C=gcd(A,B);
63         ans[index]=mkp(A/C,B/C);
64         //printf("%d ~ %d : %lld %lld\n",L,R,A,B);
65     }
66 }
67 
68 int main(){
69     while(~scanf("%d%d",&N,&M)){
70         for(int i=1;i<=N;++i)
71         scanf("%d",&a[i]);
72         chunk=sqrt(N);
73         //printf("%d is chunk of %d\n",chunk,N);
74         for(int i=1;i<=M;++i){
75             id[i]=i;
76             int u,v;
77             scanf("%d%d",&u,&v);
78             query[i]=mkp(u,v);
79         }
80         sort(id+1,id+1+M,cmp);
81         //for(int i=1;i<=M;++i) printf("%d: %d~%d\n",i,query[id[i]].fst,query[id[i]].scd);
82         solve();
83         for(int i=1;i<=M;++i){
84             printf("%lld/%lld\n",ans[i].fst,ans[i].scd);
85         }    
86     } 
87     return 0;
88 }
View Code

 

posted on 2018-08-02 22:48  Emiya_Kiritsugu  阅读(219)  评论(0编辑  收藏  举报

导航