[AcWing 887] 求组合数 III
作者:互联网
复杂度 $ g(n) \ log(n) $ (来自 OI WiKi)
总体复杂度 $ 20 \times 10^{5} \times log(10^{5}) \times log(10^{18}) = 4 \times 10^{7} $
点击查看代码
#include<iostream>
using namespace std;
typedef long long LL;
int p;
int qmi(int a, int k)
{
int res = 1;
while (k) {
if (k & 1) res = (LL) res * a % p;
k >>= 1;
a = (LL) a * a % p;
}
return res;
}
int C(int a, int b)
{
if (a < b) return 0;
int res = 1;
for (int i = 1, j = a; i <= b; i ++, j --) {
res = (LL) res * j % p;
res = (LL) res * qmi(i, p - 2) % p;
}
return res;
}
int lucas(LL a, LL b)
{
if (b == 0) return 1;
return (LL) C(a % p, b % p) * lucas(a / p, b / p) % p;
}
int main()
{
int n;
cin >> n;
while (n --) {
LL a, b;
cin >> a >> b >> p;
cout << lucas(a, b) << endl;
}
return 0;
}
- 复杂度分析
复杂度为 $ f(p) + g(n) \ log(n) $ ,其中,$ f(p) $ 为预处理组合数的复杂度, $ g(n) $ 为单次求组合数的复杂度,对应于本题中, 没有对组合数进行预处理,没有 $ f(p) $ 这一项,$ g(n) $ 是单次求组合数的复杂度,由于只有当 $ a < p $ $ , \ b < p $ 时,才会执行求组合数的函数,单次求组合数的复杂度为 $ 10^{5} \times log{10^{5}} $ ,$ log(n) $ 中的 $ n $ 是所要求的 $ C_m^{n} $ 中的 $ n $ - 卢卡斯定理
$ C_a^{b} = C_{ a / p }^{ b / p } \cdot C_{a \bmod p}^{b \bmod p} \ ( \bmod p) $ ,证明如下:
$ (1 + x)^{ p } = C_p^{0} x^{0} + C_p^{1} x^{1} + \cdots + C_p^{p} x^{p} \equiv 1 + x^{p} \ (\bmod p) $ ,$ a = a_0 p^{0} + a_1 p^{1} + \cdots + a_k p^{k} $ ,$ b = b_0 p^{0} + b_1 p^{1} + \cdots + b_k p^{k} $ ,$ (1 + x) ^ {a} = (1 + x) ^ { a_0 p^{0} + a_1 p^{1} + \cdots + a_k p^{k} } \equiv (1 + x) ^ {a_0} \ (1 + x ^ {p} ) ^ {a_1} \ \cdots \ (1 + x^{p_k} )^{a_k} $ ,两边同时求 $ x^{b} $ 的系数,可以得到 $ C_a^{b} \equiv C_{a_0}^{b_0} \ C_{a_1}^{b_1} \ \cdots \ C_{a_k}^{b_k} \ (\bmod p) $ ,这个式子和卢卡斯定理的式子是等价的;
标签:10,887,log,int,res,复杂度,cdots,III,AcWing 来源: https://www.cnblogs.com/wKingYu/p/16270345.html