1. 程式人生 > >莫隊亂搞--BZOJ2038: [2009國家集訓隊]小Z的襪子(hose)

莫隊亂搞--BZOJ2038: [2009國家集訓隊]小Z的襪子(hose)

數字 ios efi return aps log mod class print

$n \leq 50000$的$\leq 50000$的數字序列,$m \leq 50000$個詢問,每次問一個區間中隨機拿兩次(不放回)拿到相同數字的概率,以既約分數形式輸出。

莫隊入門。把詢問按“同塊排$r$、不同塊排$l$”的順序,依靠左右端點兩個指針跑來跑去依次回答。

技術分享圖片
 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 //#include<queue>
 6 //#include<time.h>
 7 //#include<complex>
8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 int n,m,lq,tot; 13 #define maxn 50011 14 #define maxm 255 15 int bel[maxn],a[maxn],cnt[maxn]; 16 struct Ques{int l,r,id;}q[maxn]; 17 bool cmp(const Ques a,const Ques b) {return bel[a.l]==bel[b.l]?a.r<b.r:a.l<b.l;}
18 19 #define LL long long 20 LL ss; 21 struct Ans{LL a,b;}ans[maxn]; 22 LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;} 23 void modify(int p,int type) {ss-=(LL)cnt[a[p]]*cnt[a[p]]; cnt[a[p]]+=type; ss+=(LL)cnt[a[p]]*cnt[a[p]];} 24 25 int main() 26 { 27 scanf("%d%d",&n,&lq); 28 m=233; for
(int i=1;i<=n;i++) bel[i]=(i-1)/m+1; tot=bel[n]; 29 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 30 for (int i=1;i<=lq;i++) scanf("%d%d",&q[i].l,&q[q[i].id=i].r); 31 sort(q+1,q+1+lq,cmp); 32 33 int L=1,R=0; ss=0; 34 for (int i=1;i<=lq;i++) 35 { 36 while (L<q[i].l) modify(L,-1),L++; 37 while (L>q[i].l) modify(L-1,1),L--; 38 while (R<q[i].r) modify(R+1,1),R++; 39 while (R>q[i].r) modify(R,-1),R--; 40 Ans &now=ans[q[i].id]; 41 now.a=ss-(q[i].r-q[i].l+1); 42 now.b=(q[i].r-q[i].l)*1ll*(q[i].r-q[i].l+1); 43 LL g=gcd(now.a,now.b); now.a/=g; now.b/=g; 44 } 45 46 for (int i=1;i<=lq;i++) printf("%lld/%lld\n",ans[i].a,ans[i].b); 47 return 0; 48 }
View Code

莫隊亂搞--BZOJ2038: [2009國家集訓隊]小Z的襪子(hose)