组合数
TimeLimit:
1
Second MemoryLimit:
32
Megabyte
Totalsubmit:
58
Accepted:
4
Description
从A
+
B个不同的物品中选择A个物品,共有多少种不同的选法。由于A,B会很大,所以结果对C取下余。
Input
首先输入T,代表共有T组测试数据。
每组数据包括三个数字,A,B,C;
Output
输出只有一个数,如题目描述。
Sample Input
2
1
1
100
2
2
100
Sample Output
2
6
开始我以为一个简单的递归就可可以过,也就是C(n,m)=C(n-1,m)+C(n-1,m-1)组合数公式,但却tle;因为题目已经说明AB会很大,那么递归与暴力枚举是不可能AC的,那么该怎么做呢?:利用素数求法:
1
#include
<
stdio.h
>
2
#include
<
string
.h
>
3
#include
<
math.h
>
4
5
#define
LEN 100000
6
#define
PLEN 9592
7
8
void
sieve (
char
*
f,
int
l ) {
9
int
i, j, ilim;
10
11
memset ( f,
0x01
, l );
12
f[
0
]
=
f[
1
]
=
0
;
13
ilim
=
(
int
) sqrt ( (
double
) l );
14
15
for
( i
=
2
; i
<=
ilim;
++
i ) {
16
if
(
!
f[i] )
continue
;
17
for
( j
=
i
*
i; j
<
l; j
+=
i ) f[j]
=
0
;
18
}
19
}
20
21
char
f[LEN];
22
int
p[PLEN];
23
int
u[PLEN], da[PLEN], db[PLEN];
24
25
void
factor (
int
n,
int
*
r )
26
{
27
int
i, j;
28
memset ( r,
0x00
, PLEN
*
sizeof
(
int
) );
29
for
( i
=
0
; i
<
PLEN;
++
i )
30
{
31
for
( j
=
n; j; r[i]
+=
( j /
=
p[i] ) );
32
}
33
}
34
35
int
main ( ) {
36
int
i, j, k;
37
int
T, A, B, C;
38
39
sieve ( f, LEN );
40
for
( i
=
2
, j
=
0
; i
<
LEN;
++
i )
if
( f[i] ) p[j
++
]
=
i;
//
p[i]初始化
41
for
(
int
i
=
0
;i
<
20
;i
++
)printf(
"
%d
"
,p[i]);
42
for
( scanf (
"
%d
"
,
&
T ); T
--
; ) {
43
scanf (
"
%d%d%d
"
,
&
A,
&
B,
&
C );
44
factor ( A
, u );
46
factor ( A, da );
47
factor ( B, db );
48
for
( i
=
0
, j
=
1
; i
<
PLEN;
++
i ) {
49
k
=
u[i]
-
da[i]
-
db[i];
50
while
( k
--
) j
=
j
*
p[i]
%
C;
51
}
52
printf (
"
%d /n
"
, j );
53
}
54
55
return
0
;
56
}