天天看點

2038. [國家集訓隊]小Z的襪子【莫隊】

Description

Input

Output

Sample Input

6 4

1 2 3 3 3 2

2 6

1 3

3 5

1 6

Sample Output

2/5

0/1

1/1

4/15

【樣例解釋】

詢問1:共C(5,2)=10種可能,其中抽出兩個2有1種可能,抽出兩個3有3種可能,機率為(1+3)/10=4/10=2/5。

詢問2:共C(3,2)=3種可能,無法抽到顔色相同的襪子,機率為0/3=0/1。

詢問3:共C(3,2)=3種可能,均為抽出兩個3,機率為3/3=1/1。

注:上述C(a, b)表示組合數,組合數C(a, b)等價于在a個不同的物品中選取b個的選取方案數。

【資料規模和約定】

30%的資料中 N,M ≤ 5000;

60%的資料中 N,M ≤ 25000;

100%的資料中 N,M ≤ 50000,1 ≤ L < R ≤ N,Ci ≤ N。

莫隊裸題

注意開long long

1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N (50000+100) 
 7 #define LL long long
 8 using namespace std;
 9 
10 struct node{LL ord,l,r,id,ans1,ans2;}Ask[N];
11 LL n,m,unit,a[N],l=1,r=0,sum,cnt[N];
12 
13 bool cmp1(node a,node b){return a.id==b.id?a.r<b.r:a.id<b.id;}
14 bool cmp2(node a,node b){return a.ord<b.ord;}
15 LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}
16 
17 
18 void Ins(LL x){sum+=cnt[a[x]]++;}
19 void Del(LL x){sum-=--cnt[a[x]];}
20 void MoQueue(LL x)
21 {
22     LL L=Ask[x].l,R=Ask[x].r;
23     while (l<L) Del(l++);
24     while (l>L) Ins(--l);
25     while (r<R) Ins(++r);
26     while (r>R) Del(r--);
27     if (L==R || sum==0)
28         Ask[x].ans1=0,Ask[x].ans2=1;
29     else
30     {
31         LL g=gcd((r-l+1)*(r-l)/2,sum);
32         Ask[x].ans1=sum/g,Ask[x].ans2=(r-l+1)*(r-l)/2/g;
33     }
34 }
35 
36 int main()
37 {
38     scanf("%lld%lld",&n,&m);
39     unit=pow(n,2.0/3.0);
40     for (LL i=1;i<=n;++i)
41         scanf("%lld",&a[i]);
42     for (LL i=1;i<=m;++i)
43     {
44         Ask[i].ord=i;
45         scanf("%lld%lld",&Ask[i].l,&Ask[i].r);
46         Ask[i].id=Ask[i].l/unit;
47     }
48     sort(Ask+1,Ask+m+1,cmp1);
49     for (LL i=1;i<=m;++i)
50         MoQueue(i);
51     sort(Ask+1,Ask+m+1,cmp2);
52     for (LL i=1;i<=m;++i)
53         printf("%lld/%lld\n",Ask[i].ans1,Ask[i].ans2);
54 }      

繼續閱讀