Atcoder 题面传送门 & 洛谷题面传送门

我竟然能独立做出 Ag 的 AGC E,incredible!更新了 Atcoder 做题难度上限(

首先按照套路 Min-Max 容斥,\(ans=\sum\limits_{\varnothing\ne T\subseteq S}(-1)^{|T|-1}\times E(\min(T))\),考虑怎样求这个式子的值。首先我们需要搞清楚 \(E(\min(T))\),假设 \(T\) 中包含下标为 \(x_1,x_2,\cdots,x_m\) 这 \(m\) 个元素,那么 \(E(\min(T))\) 的实际意义就是期望最少选多少个数就能找到一个 \(x_i\) 的出现次数达到了其上界 \(b_{x_i}\),首先有可能我们抽到的数不在 \(T\) 当中,这里有一个小套路,我们记 \(e\) 为期望多少次才能抽到一个 \(T\) 中的数,那么显然 \(e=\dfrac{\sum a_i}{\sum\limits_{x\in T}a_x}\),这样相当于我们将原来每一步的贡献 \(1\) 变成了 \(e\),因此我们只需将答案乘个 \(e\) 就可以得到最终的 \(E(\min(T))\)。这样一来我们就不用考虑不在 \(T\) 中的数的影响了,不过我们发现这东西是不太好直接求的,故我们不妨换个角度,我们假设到达最终状态时元素 \(x_i\) 被选择的 \(c_i\) 次,那么不难发现对于任意一个由初始状态 \(0,0,\cdots,0\) 到达最终状态的取数方式,它中间总要经过 \(\sum c_i\) 个满足 \(c_i<b_{x_i}\) 的状态,因此我们可以在每个中间状态中累加一次贡献,而对于一个满足 \(\forall i,c_i<b_{x_i}\) 的 \(c_1,c_2,\cdots,c_m\),只要它到达了这个状态,它就肯定会被统计入答案中,因此我们要求的实际上是所有满足满足 \(\forall i,c_i<b_{x_i}\) 的 \(c_1,c_2,\cdots,c_m\),到达 \(c_1,c_2,\cdots,c_m\) 的概率。而显然对于固定的 \(c_1,c_2,\cdots,c_m\),到达 \(c_1,c_2,\cdots,c_m\) 的概率可用总方案数除以到达 \(c_1,c_2,\cdots,c_m\) 的方案数计算,即 \(\dfrac{(\sum c_i)!}{\prod c_i!}\times\prod(\dfrac{a_i}{\sum\limits_{x\in S}a_x})^{c_i}\),第一项为多重组合数,即将 \(i\) 个 \(c_i\) 填入一排 \(c_1+c_2+\cdots+c_m\) 个数的方案数,第二项表示生成 \(c_i\) 个 \(i\) 的方案数,生成一个 \(i\) 的概率为 \(\dfrac{a_i}{\sum\limits_{x\in S}a_x}\),生成 \(c_i\) 个 \(i\) 的概率就是 \((\dfrac{a_i}{\sum\limits_{x\in S}a_x})^{c_i}\),很好理解。

因此我们有:

\[E(\min(T))=\dfrac{\sum a_i}{\sum\limits_{x\in T}a_x}\sum\limits_{c_i\lt b_{x_i}}\dfrac{(\sum c_i)!}{\prod c_i!}\times\prod(\dfrac{a_i}{\sum\limits_{x\in S}a_x})^{c_i}
\]

将其带入答案计算式可得

\[\begin{aligned}ans&=\sum\limits_{\varnothing\ne T\subseteq S}(-1)^{|T|-1}\times\dfrac{\sum a_i}{\sum\limits_{x\in T}a_x}\sum\limits_{c_i\lt b_{x_i}}\dfrac{(\sum c_i)!}{\prod c_i!}\times\prod(\dfrac{a_i}{\sum\limits_{x\in S}a_x})^{c_i}\\&=\sum\limits_{\varnothing\ne T\subseteq S}(-1)^{|T|-1}\times\dfrac{\sum a_i}{\sum\limits_{x\in T}a_x}\sum\limits_{c_i\lt b_{x_i}}\dfrac{(\sum c_i)!}{\prod c_i!}\times\prod a_i^{c_i}\times(\dfrac{1}{\sum\limits_{x\in T}a_x})^{\sum c_i}\end{aligned}
\]

注意到 \(\sum a_i\) 是定值,\(\sum\limits_{x\in T}a_x,\sum c_i\) 都不会超过 \(400\),因此考虑 \(dp\),可以将其放入背包的状态中,设 \(dp_{i,j,k}\) 表示所有 \(T\subseteq\{1,2,3,\cdots,i\}\),\(\sum\limits_{x\in T}a_x=j\),\(\sum c_i=k\) 的 \((-1)^{|T|-1}\prod\dfrac{1}{c_i!}a_i^{c_i}\) 的和,转移就分 \(i\in T\) 和 \(i\notin T\) 转移即可,若 \(i\notin T\) 则 \(dp_{i,j,k}\leftarrow dp_{i-1,j,k}\),否则我们枚举 \(c_i<b_i\),那么 \(dp_{i,j,k}\leftarrow -dp_{i-1,j,k}\times\dfrac{1}{c_i!}a_i^{c_i}\),二者相加即可,初始值 \(dp_{0,0,0}=-1\)(因为空集的 \((-1)^{|T|+1}=-1\)),求答案就枚举 \(\sum\limits_{x\in T}a_x=j,\sum c_i=k\),然后用 \(dp_{n,j,k}\times(\sum a_i)\times\dfrac{1}{j^{k+1}}\times k!\) 更新答案即可,第一维可以优化到,时间复杂度 \(\sum a_i(\sum b_i)^2\),空间复杂度 \(\sum a_i\sum b_i\),可以通过此题。

const int MAXN=400;
const int MOD=998244353;
int n,a[MAXN+5],b[MAXN+5],sa,sb,dp[MAXN+5][MAXN+5];
int inv[MAXN+5],ifac[MAXN+5],fac[MAXN+5];
void init_fac(int n){
for(int i=(inv[0]=inv[1]=ifac[0]=fac[0]=1)+1;i<=n;i++) inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) ifac[i]=1ll*ifac[i-1]*inv[i]%MOD,fac[i]=1ll*fac[i-1]*i%MOD;
}
int main(){
scanf("%d",&n);init_fac(MAXN);dp[0][0]=MOD-1;
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]),sa+=a[i],sb+=b[i];
for(int i=1;i<=n;i++){
for(int j=sa;j>=a[i];j--) for(int k=sb;~k;k--)
for(int l=0,pw=1;l<=min(k,b[i]-1);l++,pw=1ll*pw*a[i]%MOD){
dp[j][k]=(dp[j][k]-1ll*dp[j-a[i]][k-l]*pw%MOD*ifac[l]%MOD+MOD)%MOD;
}
} int ans=0;
for(int i=1;i<=sa;i++) for(int j=0,pw=1;j<=sb;j++,pw=1ll*pw*inv[i]%MOD){
ans=(ans+1ll*dp[i][j]*pw%MOD*inv[i]%MOD*sa%MOD*fac[j]%MOD)%MOD;
} printf("%d\n",ans);
return 0;
}

Atcoder Grand Contest 038 E - Gachapon(Min-Max 容斥+背包)的更多相关文章

  1. AtCoder Grand Contest 038 简要题解

    从这里开始 比赛目录 Problem A 01 Matrix Code #include <bits/stdc++.h> using namespace std; typedef bool ...

  2. AtCoder Grand Contest 038 题解

    传送门 这场表现的宛如一个\(zz\) \(A\) 先直接把前\(b\)行全写成\(1\),再把前\(a\)列取反就行 const int N=1005; char mp[N][N];int n,m, ...

  3. AtCoder Grand Contest 038题解

    好久没更了 写点东西吧= = A 01Matrix 简单构造 左上角和右下角染成1其他染成0即可 #include<bits/stdc++.h> #define ll long long ...

  4. Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)

    洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...

  5. AtCoder Grand Contest 038

    目录 \(\bf A - 01 \ Matrix\) \(\bf B- Sorting \ a \ Segment\) \(\bf C-LCMs\) \(\bf D-Unique \ Path\) 这 ...

  6. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  7. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  8. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  9. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

随机推荐

  1. Scrum Meeting 14

    第14次例会报告 日期:2021年06月07日 会议主要内容概述: 汇报了已完成的工作,明确了下一步目标,正在努力赶进度. 一.进度情况 我们采用日报的形式记录每个人的具体进度,链接Home · Wi ...

  2. the Agiles Scrum Meeting 博客汇总

    the Agiles 团队博客目录 一.Scrum Meeting 1. Alpha the Agiles Scrum Meeting 1 the Agiles Scrum Meeting 2 the ...

  3. Go语言核心36讲(Go语言进阶技术八)--学习笔记

    14 | 接口类型的合理运用 前导内容:正确使用接口的基础知识 在 Go 语言的语境中,当我们在谈论"接口"的时候,一定指的是接口类型.因为接口类型与其他数据类型不同,它是没法被实 ...

  4. 看动画学算法之:双向队列dequeue

    目录 简介 双向队列的实现 双向队列的数组实现 双向队列的动态数组实现 双向队列的链表实现 双向链表的时间复杂度 简介 dequeue指的是双向队列,可以分别从队列的头部插入和获取数据,也可以从队列的 ...

  5. 20191310李烨龙Linux C语言编程基础

    Linux C语言编程基础 任务详情 0. 基于Ubuntu或OpenEuler完成下面的任务(OpenEuler有加分) 1. 选择教材第二章的一节进行编程基础练习(2.10,2.11,2.12,2 ...

  6. cesium制作自己的骑行轨迹

    制作自己的骑行轨迹 马上国庆节了,计划骑车回家,突然想到把所有的骑行线路汇总一下,无奈码表和APP不支持这样的操作,出于职业病,在此操作一下. 我用的是黑鸟码表,可以导出fit运动轨迹,但是fit还需 ...

  7. linux环境下redis安装(redis伪集群搭建)

    redis在linux环境下搭建 1.创建目录 [root@192 local]# mkdir /usr/local/redis 2.下载redis,并解压 [root@192 local]# wge ...

  8. Dataworks批量刷数优化方案探讨

    Dataworks批量刷数优化方案探讨 在数据仓库的日常使用中,经常会有批量补数据,或者逻辑调整后批量重跑数据的场景. 批量刷数的实现方式,因调度工具差异而各有不同. Dataworks调度批量刷数局 ...

  9. 力扣 - 剑指 Offer 06. 从尾到头打印链表.md

    题目 剑指 Offer 06. 从尾到头打印链表 思路1(递归) 首先先遍历整个脸表,计算出链表的长度(用于初始化数组).然后进行递归,从链表头部递归到尾部,这期间什么都不做,直到递归到最后一个节点的 ...

  10. elementUI合并表格span-method用法

    官方文档 参考链接一 参考链接二