HDU - 6397 Character Encoding 【容斥】 经典问题方程的解!!! 好题! 多校

本文探讨了组合数学在解决特定类型算法竞赛题目中的应用,重点讲解了如何使用容斥原理来解决带有上界限制的多项式方程的正整数解数目问题。文章详细解释了隔板法的基本原理,并通过实例演示了如何通过预处理阶乘及其逆元来快速计算组合数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门
题意:
求 x1 + x2 + …. + xm = k (0 <= xi < n), 这个方程的正整数解.

很明显, 如果xi>=0, 没有上界, 那么方程的解数为C(m-1, k+m-1), 可以用隔板法证明. 同理如果xi > 0, 那么解为C(m-1, k-1).

那么加了上界怎么判, 很明显我们就用总的去减, 但是会减重, 所以就是容斥, 容斥系数很容易推导为(-1)^c, c表示这m个变量中有c个违反了上界, 那么原方程变为 x1’ + x2’ + …. + xm’ = k - c*n, 其中xi’ = xi >= n ? xi-n : xi; 所以这个方程同理也能推出解为C(k - c*n + m -1, m -1); 然后再把容斥系数乘上就OK了.

注意要预处理出所有阶乘以及所有阶乘的逆元, 利用性质可以在O(n)的时间内预处理出来. 细节请看代码实现.

AC Code

const int maxn = 2e5+5;
ll inv[maxn], fac[maxn], infac[maxn];
void init() {
    fac[0] = 1;
    for(ll i = 1 ; i < maxn ; i ++) fac[i] = (fac[i-1]*i) % mod;  // 初始化n!数组.
    inv[1] = 1;
    for (int i = 2 ; i < maxn ; i ++) {
        inv[i] = (mod - mod / i) * inv[mod % i] % mod;
    }
    infac[0] = 1;
    for (int i = 1 ; i < maxn ; i ++) {
        infac[i] = infac[i-1] * inv[i] % mod;
    }
}
ll Comb(ll m, ll n) {
    return fac[m] * infac[n] % mod * infac[m-n] % mod;
}
ll work(ll m, ll n) {
    if (m < n) return 0;
    return Comb(m, n);
}
void solve() {
    ll n, m, k;
    scanf("%lld%lld%lld", &n, &m, &k);
    ll ans = 0;
    for (ll i = 0 ; i <= m ; i ++) {
        ll tmp = Comb(m, i) * work(k-i*n+m-1, m-1) % mod;
        if (i&1) ans -= tmp;
        else ans += tmp;
        ans = (ans % mod + mod) % mod;
    }
    printf("%lld\n", ans);
}

记住这一类的好题!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值