組合數取餘


即計算 Cnm%pC_n^m\%p .
n,mn, m 比較大時,就可以爆掉long long的範圍了(據大佬說大概 n=60n=60 就會爆了). 本蒟蒻就不驗證了,相信大佬的 . 其實你算個階乘就可以了

使用C++庫函數

可以使用一個衆所周知的數學定理
n,m50n,m\le50,使用C++庫函數tagamma .

double tgamma(double x);

tgammatgamma 是一個歐拉積分
Γ(s)=0xs1exdx \varGamma(s) = \int_{0}^{\infty} x^{s-1}e^{-x}dx\qquad
理解不了不重要,只要會用下面這個結論就行了

在整數點處取值滿足
Γ(n+1)=n! \varGamma(n+1) = n!
代碼十分簡短 .

LL get_c(LL n, LL m)
{
        return (LL)round(tgamma(n+1)/tgamma(m+1)/tgamma(n-m+1));
}

利用楊輝恆等式

楊輝三角,是二項式係數在三角形中的一種幾何排列,

1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1

不知道怎麼搞居中,但相信你們能懂我意思

C00C_0^0
C10  C21  C11C_1^0 \space \space C_2^1 \space \space C_1^1
C20  C31  C32  C33C_2^0 \space \space C_3^1 \space \space C_3^2 \space \space C_3^3
C30  C41  C42  C43  C44C_3^0 \space \space C_4^1 \space \space C_4^2 \space \space C_4^3 \space \space C_4^4
C40  C51  C52  C53  C54  C55C_4^0 \space \space C_5^1 \space \space C_5^2 \space \space C_5^3 \space \space C_5^4 \space \space C_5^5

顯而易見,得出楊輝恆等式: Cnm=Cn1m1+Cn1mC_n^m = C_{n-1}^{m-1} + C_{n-1}^m

如果 n,mn,m 不大(可以開 O(n2)O(n^2) 的空間),我們就可以開心暴力地打個表了 .

LL __[maxn][maxn];
LL get_c(LL n)
{
        for (int i = 0; i <= n; i++)
                for (int j = 0; j <= i; j++)
                        __[i][j] = (j == 0 || j == i) ? 1 : (__[i-1][j-1]+__[i-1][j])%mod;
}

利用逆元

如果 nn 已經不滿足前面兩種情況,在保證模數爲素數的情況下,可以用逆元求解. 可以開 O(n)O(n) 的空間.


#define LL long long
const int mod = 1e9+10;
const int maxn = 1e5+10;
LL get_c(LL n, LL m)
{
        static LL M = 0, in[maxn], mul[maxn] = {1}, ans[maxn] = {1};
        while (++M <= n)
        {
                in[M] = M == 1 ? 1 : (mod - mod/M) * in[mod%M] % mod;
                mul[M] = mul[M-1]*M%mod;
                ans[M] = ans[M-1] * in [M] % mod;
        }
        return mul[n]*ans[m] % mod * ans[n-m] % mod;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章