Desserts(组合数学 + 思维)

该篇博客探讨了一个糖果分配问题,要求将n种糖果分给k支队伍,每队糖果类型不重复。原始暴力解法由于复杂度过高会导致超时。作者提出优化策略,利用组合数学和快速幂计算,当糖果总数不超过10^5时,通过枚举不同类型的糖果数量并快速计算方案数,降低了时间复杂度到O(m * √(∑ai) * logn)。AC代码中展示了实现细节。
摘要由CSDN通过智能技术生成

题目链接:Desserts

题目大意:

有 n 种糖果,第 i 种糖果共有 ai 个,问把所有糖果分给 k 支队伍,使得每支队伍不会拥有相同类型糖果的方案数。保证 ∑ a i \sum ai ai   1 0 5 \ 10^5  105

解题思路:

首先,考虑暴力做法,对于第 i 种糖果分给 k 支队伍的方法有 C k a i C_{k}^{ai} Ckai 种, 则ans = ∏ i = 1 n C k a i \prod_{i=1}^n{C_{k}^{ai}} i=1nCkai。可以看出这样复杂度为O(nm),会超时,所以我们应该想办法优化一下。

∑ a i \sum{ai} ai   1 0 5 \ 10^5  105 可以推出不同的 ai 最多有 ∑ a i \sqrt{\sum ai} ai 种,所以直接枚举不同的 ai ,然后相同的 ai 快速幂贡献在一起即可。这样复杂度就成了O(m ∑ a i \sqrt{\sum ai} ai logn)

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int mod = 998244353;
int fact[N], infact[N], a[N];
int n, m;
unordered_map<int, int> mp;
int qmi(int a, int k, int p)
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = (ll)res * a % p;
        a = (ll)a * a % p;
        k >>= 1;
    }
    return res;
}
int main()
{
    fact[0] = infact[0] = 1;
    for (int i = 1; i <= 1e5; i++)
    {
        fact[i] = (ll)fact[i - 1] * i % mod;
        infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
    }
    scanf("%d%d", &n, &m);
    int maxx = 0;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        mp[a[i]]++;
        maxx = max(maxx, a[i]);
    }
    for (int i = 1; i <= m; i++)
    {
        if (i < maxx) puts("0");
        else
        {
            ll ans = 1;
            for (auto &u : mp)
            {
                int x = u.first, y = u.second;
                ans = ans * qmi((ll)fact[i] * infact[x] % mod * infact[i - x] % mod, y, mod) % mod;
            }
            printf("%lld\n", ans);
        }
    }
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值