模板题
VJudge: Pink Elephants
输入m, n
求解
C
n
m
%
p
C^m_n\%p
Cnm%p
杨辉三角
0 ≤ m ≤ n ≤ 1000 0\le m \le n \le 1000 0≤m≤n≤1000 , 1 ≤ p ≤ 1 e 9 1 \le p \le 1e9 1≤p≤1e9 时使用
int dp[250][250];
const int p = 1000000007;
signed main() {
//#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
//#endif
int a, b; cin >> a >> b;
for(int i = 0; i<220; i++){
for(int j = 0; j<=i; j++){
if(j == 0 || i == j) dp[i][j] = 1;
else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j])%p;
}
}
cout << dp[b][a];
return 0;
}
阶乘逆元
可以用线性复杂度预处理进行优化。
同余定理+逆元: https://blog.csdn.net/LOOKQAQ/article/details/81282342
int fact[250];
const int mod = 1000000007;
int fastPow(int base, int power, int p) {
int ans = 1;
while (power > 0) {
if (power & 1) {
ans = ans * base % p;
}
power >>= 1;
base = base * base % p;
}
return ans;
}
int inv(int a, int p){
return fastPow(a, p-2, mod);
}
signed main() {
//#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
//#endif
int m, n; cin >> m >> n;
fact[0] = 1;
for(int i = 1; i<=220; i++){
fact[i] = i * fact[i-1] % mod;
}
cout << fact[n] * inv(fact[m], mod) % mod * inv(fact[n-m], mod) % mod;
return 0;
}
卢卡斯定理
原理:
L
u
c
a
s
(
n
,
m
,
p
)
m
o
d
p
=
L
u
c
a
s
(
n
p
,
m
p
,
p
)
∗
C
n
m
o
d
p
m
m
o
d
p
m
o
d
p
Lucas(n ,m, p)\ mod\ p\ = Lucas(\frac{n}{p}, \frac{m}{p}, p) * C^{m\ mod\ p}_{n\ mod\ p}\ mod\ p
Lucas(n,m,p) mod p =Lucas(pn,pm,p)∗Cn mod pm mod p mod p
L
u
c
a
s
(
n
,
m
,
p
)
m
o
d
p
=
C
n
m
m
o
d
p
Lucas(n ,m, p)\ mod\ p = C^m_n\ mod\ p
Lucas(n,m,p) mod p=Cnm mod p
int fact[250];
const int mod = 1000000007;
int fastPow(int a, int b, int p)
{
int ans = 1;
a %= p;
while(b)
{
if(b & 1)
{
ans = ans * a % p;
b--;
}
b >>= 1;
a = a * a % p;
}
return ans;
}
int C(int n, int m, int p) {
if (m > n) return 0;
return (((fact[n] * fastPow(fact[m], p - 2, p)) % p) * fastPow(fact[n - m], p - 2, p)) % p;
}
int lucas(int n, int m, int p) {
if (!m) return 1;
return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;
}
signed main() {
//#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
//#endif
int m, n;
cin >> m >> n;
fact[0] = 1;
for (int i = 1; i <= 220; i++) {
fact[i] = i * fact[i - 1] % mod;
}
cout << lucas(n, m, mod);
return 0;
}