IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2021 CCPC 威海赛区G题 Desserts -> 正文阅读

[数据结构与算法]2021 CCPC 威海赛区G题 Desserts

2021 CCPC 威海赛区G题 Desserts

题解

n n n种类型的糖果(第 i i i种糖果有 a i a_i ai?个)要分给 k ( k = [ 1 , m ] ) k(k=[1,m]) k(k=[1,m])个队伍,每个队伍在同一种类型的糖果只能拿出一个

现在要将所有的糖果发完,求有多少种方案。

数据范围满足 n , m ≤ 5 ? 1 0 4 , ∑ i = 1 n a i ≤ 1 0 5 n,m\le 5\cdot 10^4,\sum_{i=1}^na_i\le 10^5 n,m5?104,i=1n?ai?105

思路

先考虑暴力的做法,当需要分给 k k k个队伍时,结果为 ∏ i = 1 n C k a i \prod_{i=1}^{n}C_k^{a_i} i=1n?Ckai??(从 k k k个队伍中选出 a i a_i ai?个队分发第 i i i种糖果),组合数可以做预处理。
暴力去枚举 k k k时,复杂度为 O ( m ? n ) O(m\cdot n) O(m?n),会超时。

计算 ∏ i = 1 n C k a i \prod_{i=1}^{n}C_k^{a_i} i=1n?Ckai??时,如果将相同的 a i a_i ai?放在一起,答案就变成了 ∏ i = 1 n ′ ( C k a i ) p i \prod_{i=1}^{n'}{(C_k^{a_i})}^{p_i} i=1n?(Ckai??)pi?
例如: C k 1 C k 2 C k 2 C k 3 C k 3 C k 3 = ( C k 1 ) ( C k 2 ) 2 ( C k 3 ) 3 C_k^1C_k^2C_k^2C_k^3C_k^3C_k^3=(C_k^1)(C_k^2)^2(C_k^3)^3 Ck1?Ck2?Ck2?Ck3?Ck3?Ck3?=(Ck1?)(Ck2?)2(Ck3?)3

同时可以注意到题目中有一个条件是: ∑ i = 1 n a i ≤ 1 0 5 \sum_{i=1}^na_i\le 10^5 i=1n?ai?105,那么 n ′ n' n最大为 1 0 5 \sqrt {10^5} 105 ?。(想了半天也没想到这个条件可以这么用
可以先预处理出来 p p p,然后计算时使用快速幂,这样就可以确保复杂度可以通过题目。

AC的代码

#include <bits/stdc++.h>
#define ll long long
#define pub push_back
#define sz(x) (int)(x).size()
using namespace std;

const int mod = 998244353;
const int N = 1e5 + 10;

ll power(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}

ll inv(ll x) { return power(x, mod - 2); }

int n, m, a[N], p[N];
int vis[N];
ll fac[N], inv_f[N];

void init() {
    fac[0] = 1;
    for (int i = 1; i <= N - 10; i++) fac[i] = fac[i - 1] * i % mod;
    inv_f[N - 10] = inv(fac[N - 10]);
    for (int i = N - 11; i >= 0; i--) inv_f[i] = inv_f[i + 1] * (i + 1) % mod;
}

ll C(ll n, ll m) {
    if (m > n) return 0;
    return fac[n] * inv_f[m] % mod * inv_f[n - m] % mod;
}

int main() {
    init();
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];

    vector<int> vec;  // 最多sqrt(1e5)个
    for (int i = 1; i <= n; i++) {
        p[a[i]]++;
        if (vis[a[i]]) continue;
        vis[a[i]] = 1;
        vec.pub(a[i]);
    }

    for (int k = 1; k <= m; k++) {
        ll res = 1;
        for (auto it : vec) res = res * power(C(k, it), p[it]) % mod;

        cout << res << "\n";
    }

    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:37:09  更:2021-11-23 12:39:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 10:57:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码