比赛 组合计数1 评测结果 WWWWWWTTTTWWWTTTTTTT
题目名称 组合数问题 最终得分 0
用户昵称 对立猫猫对立 运行时间 13.413 s
代码语言 C++ 内存使用 3.50 MiB
提交时间 2026-02-26 09:28:30
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
int n, p, k, r, aa, bb, ans;
void exgcd(int a, int b, int &aa, int &bb)
{
    if(!b)
    {
        aa = 1; bb = 0;
    }
    else
    {
        exgcd(b, a % b, bb, aa); bb -= aa * (a / b);
    }
    return;
}
int calc(int l, int r, int p)
{
    int ans = l;
    for(int i = l + 1; i <= r; i++)
    {
        ans *= i;
        ans %= p;
    }
    return ans;
}
int kasumi(int a, int k, int p)
{
    if(k == 0) return 1 % p;
    if(a == 1) return 1 % p;
    int ans = 1;
    while(k)
    {
        if(k & 1) ans *= a, ans %= p;
        a *= a;
        a %= p;
        k >>= 1;
    }
    return ans;
}
int Catlan(int k, int n, int p)
{
    int ans = calc(1, n, p);
    int t = calc(1, n - k, p) * calc(1, k, p);
    t %= p;
    aa = 0;
    bb = 0;
    exgcd(t, p, aa, bb);
    aa %= p;
    while(aa <= 0) aa += p;
    ans *= aa;
    ans %= p;
//    ans *= kasumi(t, p - 2, p);
//    ans %= p;
    return ans;
}
int main() {
    freopen("problem.in", "r", stdin);
    freopen("problem.out", "w", stdout);
    cin >> n >> p >> k >> r;
    for(int i = 0; i <= n; i++) {
//        cout << Catlan(i * k + r, n * k, p) << " ";
        ans += Catlan(i * k + r, n * k, p);
        ans %= p;
    }
    cout << ans << endl;
    return 0;
}