Description
LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样。那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值。(1<=m<=n<=200,000,000)
输出C(n, m) mod 10007
Solution
lucas定理的基本应用
C(n,m)%p=C(⌊np⌋,⌊mp⌋)%p∗C(n%p,m%p)%p
C
(
n
,
m
)
%
p
=
C
(
⌊
n
p
⌋
,
⌊
m
p
⌋
)
%
p
∗
C
(
n
%
p
,
m
%
p
)
%
p
预处理阶乘和逆元搞一个递归就ok
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int MOD=10007;
LL ny[MOD+1],fac[MOD+1];
LL ksm(LL x,LL dep) {
if (dep==0) return 1;
if (dep==1) return x;
LL tmp=ksm(x,dep/2);
if (dep%2) return tmp*tmp%MOD*x%MOD;
return tmp*tmp%MOD;
}
LL C(LL n,LL m) {
LL ret=fac[n]*ny[m]%MOD*ny[n-m]%MOD;
return ret;
}
LL lucas(LL n,LL m) {
LL ret=1;
while (n*m) {
if (n%MOD<m%MOD) return 0;
ret=(ret*C(n%MOD,m%MOD))%MOD;
n=n/MOD; m=m/MOD;
}
return ret;
}
int main(void) {
fac[0]=ny[0]=1;
fac[1]=ny[1]=1;
rep(i,2,MOD) fac[i]=fac[i-1]*i%MOD;
rep(i,2,MOD) ny[i]=ksm(fac[i],MOD-2);
int T; scanf("%d",&T);
while (T--) {
LL n,m; scanf("%lld%lld",&n,&m);
LL ans=lucas(n,m);
printf("%lld\n", ans);
}
return 0;
}