abc042d <组合数>

https://atcoder.jp/contests/abc042/tasks/arc058_b

// 分成两段, 计算组合数, 枚举分段点; 注意组合数需要使用递推, 否则超时
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;

int qpow(int a, int k, int m)
{
    a %= m;
    int res = 1;
    while (k)
    {
        if (k & 1) res = 1ll * res * a % m;
        k >>= 1;
        a = 1ll * a * a % m;
    }
    return res;
}


int C(int n, int k)
{
    if (k < 0 || k > n)  return 0;
    int res = 1;
    int t = 1;
    for (int i = 1, j = n; i <= k; i ++, j --)
    {
        res = 1ll * res * j % mod;
        t = 1ll * t * qpow(i, mod - 2, mod) % mod;
    }
    return 1ll * res * t % mod;
}

void solv()
{
    int h, w, a, b;
    cin >> h >> w >> a >> b;
    int res = 0;
    int row = h - a;
    int t1, t2;
    for (int col = b + 1; col <= w; col ++)
    {
        if (col == b + 1)
        {
            t1 = C(row + col - 2, col - 1);
            t2 = C((a-1)+ (w-col), a-1);
        }
        else  // 组合数递推
        {
            t1 = 1ll * t1 * (row+col-2) % mod * qpow(col-1, mod-2, mod) % mod;
            t2 = 1ll * t2 * (w - col + 1) %mod * qpow(a-1+w-col+1, mod-2, mod) % mod;
        }

        int t = 1ll * t1 * t2 % mod;
        res = (1ll * res + t) % mod;
        // cout << "col " << col  << " , row = " << row << "   t1 = " << t1 << "   t2 = " << t2 << endl;
    }
    cout << res << endl;

}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T --)
    {
        solv();
    }
    return 0;
}
posted @   O2iginal  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示