题意:
一共n个元素,从中选取m个元素,满足选出的元素中没有相邻的元素,一共有多少种选法
题解:
插板法:
从n个数中选择m个数,剩下的数为n-m,可以产生
n
−
m
+
1
n-m+1
n−m+1个空,这道题就变成了把m个数插到这
n
−
m
+
1
n-m+1
n−m+1个空中有多少种方法,即
C
n
−
m
+
1
m
C_{n-m+1}^{m}
Cn−m+1m
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define ls o<<1
#define rs o<<1|1
#define fi first
#define se second
#define CLR(a, b) memset(a, (b), sizeof(a))
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 1e4+10;
void F() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
}
ll pow_mod(ll a, ll b, ll p) {
ll res = 1;
while(b) {
if(b&1) res = res*a%p;
a = a*a%p;
b >>= 1;
}
return res;
}
ll inv(ll x, ll p) {
return pow_mod(x, p-2, p);
}
ll C(ll a, ll b, ll p) {
if(a < b) return 0LL;
ll ans = 1LL;
for(int i = 1; i <= b; ++i ) {
ans = ans*(((a+i-b)%p)*inv(i, p)%p)%p;
}
return ans;
}
ll lucas(ll a, ll b, ll p) {
if(b == 0) return 1;
return C(a%p, b%p, p)*lucas(a/p, b/p, p)%p;
}
int main() {
// F();
ll a, b, p;
while(cin >> a >> b >> p) {
cout << lucas(a-b+1, b, p)%p << endl;
}
return 0;
}