【洛谷 P1641】 [SCOI2010]生成字符串(Catalan數)

題目鏈接
可以看成在座標系中從\((0,0)\)\(n+m\)步走到\((n+m,n-m)\)的方案數,只能向右上\((1)\)或者右下\((0)\)走,而且不能走到\(y=-1\)這條直線上。
不考慮最後那個限制條件的話就是\(n+m\)次中選\(m\)次往右下走,即\(C(n+m,m)\)
然後根據對稱原理,從\((0,0)\)走到\(y=-1\)上就相當於從\((0,-2)\)走到\(y=-1\)上,其方案數是一樣的,所以經過\(y=-1\)的方案數其實就是從\((0,-2)\)走到\((n+m,n-m)\)的方案數,也就是\(C(n+m,m-1)\)
所以這題唯一的標籤“逆元”也只是用來求組合數的而已。

#include <cstdio>
#define ll long long
int n, m;
const int MOD = 20100403;
void exgcd(ll &x, ll &y, ll a, ll b){
    if(!b){ x = 1; y = 0; return; }
    exgcd(x, y, b, a % b);
    ll z = x; x = y; y = z - a / b * y;
}
int fact[2000010];
ll x, y, X, Y;
int C(int n, int m){
    exgcd(x, y, fact[m], MOD); exgcd(X, Y, fact[n - m], MOD);
    return ((ll)fact[n] * x % MOD * X % MOD + MOD) % MOD;
}
int main(){
    fact[0] = 1;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= 2000000; ++i)
        fact[i] = (ll)fact[i - 1] * i % MOD;
    printf("%d\n", ((C(n + m, m) - C(n + m, m - 1)) % MOD + MOD) % MOD);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章