【ybtoj高效进阶6-4-2】方案统计
题目大意:
给定 n,m 求 C n m m o d 10007 C_{n}^{m}\bmod 10007 Cnmmod10007的值。
思路:
n,m的范围都比 10007 大,使用卢卡斯定理
C
n
m
=
C
n
/
p
m
/
p
∗
C
n
m
o
d
p
m
m
o
d
p
C_{n}^{m}=C_{n/p}^{m/p}*C_{n\bmod p}^{m\bmod p}
Cnm=Cn/pm/p∗Cnmodpmmodp
不会卢卡斯定理的 戳这里
这是一道比模板题还模板题的题。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e5+10,p=10007;
ll t,n,m;
ll jc[V],inv[V];
ll qpow (ll x,ll y,ll p)
{
ll ans=1;
while(y)
{
if(y&1) ans=(ans*x)%p;
x=(x*x)%p;
y>>=1;
}
return ans;
}
ll f(ll n,ll m)
{
if(m>n) return 0;
return (jc[n]*inv[m])%p*inv[n-m]%p;
}
ll C(ll n,ll m)
{
if(m==0) return 1;
return (C(n/p,m/p)*f(n%p,m%p)%p)%p;
}
int main()
{
scanf("%lld",&t);
jc[0]=1;
rep(i,1,p) jc[i]=(jc[i-1]*i)%p;
inv[p-1]=qpow(jc[p-1],p-2,p);
per(i,p-2,0) inv[i]=(inv[i+1]*(i+1))%p;
while(t--)
{
scanf("%lld%lld",&n,&m);
printf("%lld\n",C(n,m));
}
return 0;
}