其他分享
首页 > 其他分享> > [AcWing 887] 求组合数 III

[AcWing 887] 求组合数 III

作者:互联网

image

复杂度 $ 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;
}

  1. 复杂度分析
    复杂度为 $ 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 $
  2. 卢卡斯定理
    $ 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