#include<iostream>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 7;
ll n, m, p;
ll fac[maxn];
void init_fac() {
//阶乘打表
fac[0] = 1;
for (ll i = 1; i <= p; i++) {
fac[i] = (fac[i - 1] * i) % p;
}
}
ll quick_pow(ll a, ll b) {
//a的逆元pow(a, p - 2) p为质数
ll ans = 1;
while (b) {
if (b & 1) {
ans = (ans * a) % p;
}
a = (a * a) % p;
b >>= 1;
}
return ans;
}
ll C(ll n, ll m) {
//求1e6以内的组合数的常规方法
if (n < m) return 0; //特判一下n < m的情况
ll up = fac[n];
ll down = fac[n - m] * fac[m] % p;
down = quick_pow(down, p - 2); //求分母的逆元
ll ans = up * down % p; //返回C(n, m)
return ans;
}
ll Lucas(ll n, ll m) {
//记板子吧!!!不好推导
if (m == 0) return 1;
else return Lucas(n / p, m / p) * C(n % p, m % p) % p;
}
int main() {
cin >> n >> m >> p;
init_fac(); //阶乘打表
cout << Lucas(n, m) << endl;
return 0;
}
模板——Lucas(大组合数取模)
猜你喜欢
转载自blog.csdn.net/qq_45739057/article/details/105547554
今日推荐
周排行