首页 > 代码库 > bzoj4809 -- 组合数

bzoj4809 -- 组合数

容易看出答案就是C(n,m)。。。

然后高精乘一下就可以了。

对n!分解质因数时,质数p的出现次数是n/p+n/p^2+n/p^3+...

 

代码:

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 101
 7 inline int Min(int x,int y){return x<y?x:y;}
 8 inline int Max(int x,int y){return x<y?y:x;} 
 9 struct bign  
10 {  
11     int len, s[MAXN];  
12     bign ()  
13     {  
14         memset(s, 0, sizeof(s));  
15         len = 1;  
16     }  
17     bign (int num) { *this = num; }  
18     bign (const char *num) { *this = num; }  
19     bign operator = (const int num)  
20     {  
21         char s[MAXN];  
22         sprintf(s, "%d", num);  
23         *this = s;  
24         return *this;  
25     }  
26     bign operator = (const char *num)  
27     {  
28         for(int i = 0; num[i] == 0; num++) ;
29         len = strlen(num);  
30         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - 0;  
31         return *this;  
32     }
33     void clean()  
34     {
35         if(len>50)len=50;
36         while(len > 1 && !s[len-1]) len--;  
37     }
38     bign operator * (const bign &b)  
39     {  
40         bign c;  
41         c.len = len + b.len;  
42         for(int i = 0; i < len; i++)  
43         {  
44             for(int j = 0; j < b.len; j++)  
45             {  
46                 c.s[i+j] += s[i] * b.s[j];  
47             }  
48         }  
49         for(int i = 0; i < c.len; i++)  
50         {  
51             c.s[i+1] += c.s[i]/10;  
52             c.s[i] %= 10;  
53         }  
54         c.clean();  
55         return c;  
56     }  
57     bign operator *= (const bign &b)  
58     {  
59         *this = *this * b;  
60         return *this;  
61     }  
62 }n;  
63 int i,k,N,M,P[1000010],tot,p[1000010];
64 bool b[1000010];
65 long long j;
66 int main()
67 {
68     scanf("%d%d",&N,&M);
69     if(N<M)swap(N,M);
70     for(i=2;i<=N;i++){
71         if(!b[i])P[++tot]=i;
72         for(j=1;P[j]*i<=N&&j<=tot;j++){
73             b[P[j]*i]=1;
74             if(!(i%P[j]))break;
75         }
76     }
77     for(i=1;i<=tot;i++)
78     for(j=P[i];j<=N;j=j*P[i])p[i]+=N/j;
79     for(i=1;i<=tot;i++)
80     for(j=P[i];j<=M;j=j*P[i])p[i]-=M/j;
81     for(i=1;i<=tot;i++)
82     for(j=P[i];j<=N-M;j=j*P[i])p[i]-=(N-M)/j;
83     n=1;
84     for(i=1;i<=tot;i++)
85     for(j=0;j<p[i];j++)n*=P[i];
86     for(i=n.len-1;i>=0;i--)putchar(n.s[i]+48);
87     return 0;
88 }
bzoj4809

 

bzoj4809 -- 组合数