题
意
:
从
n
数
中
选
出
m
个
数
,
要
求
任
意
两
个
数
不
相
邻
,
求
方
案
数
题意:从n数中选出m个数,要求任意两个数不相邻,求方案数
题意:从n数中选出m个数,要求任意两个数不相邻,求方案数
题
解
:
n
个
数
中
取
m
个
,
则
还
剩
下
n
−
m
个
数
,
可
以
产
生
n
−
m
+
1
个
空
,
将
m
个
数
插
进
这
些
空
中
题解:n个数中取m个,则还剩下n-m个数,可以产生n-m+1个空,将m个数插进这些空中
题解:n个数中取m个,则还剩下n−m个数,可以产生n−m+1个空,将m个数插进这些空中
答
案
就
是
C
(
m
n
−
m
+
1
)
答案就是C\tbinom{m}{n-m+1}
答案就是C(n−m+1m)
m
o
d
  
p
\mod p
modp
n 很 大 , 而 且 p 保 证 是 质 数 , 直 接 上 L u c a s n很大,而且p保证是质数,直接上Lucas n很大,而且p保证是质数,直接上Lucas
#include<cstdio>
#include<iostream>
#define maxn 10010
#define ll long long
using namespace std;
ll n,m,p;
ll quickpow(ll A,ll B,ll mod){
A%=mod;
ll ans=1;
while(B)
{
if(B&1)
ans=(ans*A)%mod;
A=(A*A)%mod;
B>>=1;
}
return ans%mod;
}
ll CC(ll n,ll m){
if(m > n) return 0;
ll sum1 = 1,sum2 = 1;
for(int i = 1; i <= m; i++){
sum1 = (sum1*(m-i+1))%p;
sum2 = (sum2*(n-i+1))%p;
}
return sum2*quickpow(sum1,p-2,p)%p;
}
ll Lucas(ll n,ll m){
if(!m) return 1;
return CC(n%p,m%p)*Lucas(n/p,m/p)%p;//注意取模
}
int main(){
while(~scanf("%lld%lld%lld",&n,&m,&p)){
ll ans = Lucas(n-m+1,m)%p;
printf("%lld\n",ans%p);
}
return 0;
}