Solution -「ABC 215H」Cabbage Master
\(\mathcal{Description}\)
Link.
有 \(n\) 种颜色的,第 \(i\) 种有 \(a_i\) 个,任意两球互不相同。还有 \(m\) 个盒子,每个盒子可以被放入某些颜色的小球,且第 \(i\) 个盒子要求放入总数不少于 \(b_i\)。你要拿走尽量少的球,使得要求无法被满足,并求出此时拿球方案数模 \(998244353\) 的值。
\(n\le20\),\(m\le10^4\)。
\(\mathcal{Solution}\)
如果保持清醒地做这道题还是比较简单的。
首先用 Hall 定理转化合法条件,记 \(A=\{a_n\}\),\(B=\{b_m\}\),\(\operatorname{adj}(S\subseteq B)\) 表示 \(S\) 内的 \(b\) 所邻接的 \(a\) 的并,则合法条件为
\]
那么可以得知非法条件。固定 \(\operatorname{adj}(S)\),显然 \(b\) 能多选就多选,最终能得到最小取球数量为
\]
令集族 \(\mathcal S=\arg \min_{\operatorname{adj}(S)}\left\{\sum_{a\in\operatorname{adj}(S)}a-\sum_{\operatorname{adj}(\{b\})\subseteq\operatorname{adj}(S)}b+1\right\}\),也能避免算重地求出方案数为:
\]
其中 \(f(T,c)\) 表示在集合 \(T\) 内的 \(a\) 中一共选走 \(c\) 个,且每个 \(a\) 至少被选走一个的方案数,可以容斥计算。具体实现上,用几次 FWT 即可。复杂度 \(\mathcal O(nm+2^nn)\)。
\(\mathcal{Code}\)
/*~Rainybunny~*/
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
inline void chkmin( int& a, const int b ) { b < a && ( a = b ); }
const int MAXN = 20, MAXM = 1e4, MAXV = 2e6, MOD = 998244353;
int n, m, a[MAXN + 5], b[MAXM + 5], adj[MAXM + 5], sum[1 << MAXN];
int fac[MAXV + 5], ifac[MAXV + 5], tot[1 << MAXN];
int cvr[1 << MAXN], chs[1 << MAXN];
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline int mpow( int a, int b ) {
int ret = 1;
for ( ; b; a = mul( a, a ), b >>= 1 ) ret = mul( ret, b & 1 ? a : 1 );
return ret;
}
inline void init( const int s ) {
fac[0] = 1;
rep ( i, 1, s ) fac[i] = mul( i, fac[i - 1] );
ifac[s] = mpow( fac[s], MOD - 2 );
per ( i, s - 1, 0 ) ifac[i] = mul( ifac[i + 1], i + 1 );
}
inline int comb( const int a, const int b ) {
return a < b ? 0 : mul( fac[a], mul( ifac[b], ifac[a - b] ) );
}
inline void fwtAND( const int len, int* u, const auto& adf ) {
for ( int stp = 1; stp < len; stp <<= 1 ) {
for ( int i = 0; i < len; i += stp << 1 ) {
rep ( j, i, i + stp - 1 ) {
adf( u[j], u[j + stp] );
}
}
}
}
inline void fwtOR( const int len, int* u, const auto& adf ) {
for ( int stp = 1; stp < len; stp <<= 1 ) {
for ( int i = 0; i < len; i += stp << 1 ) {
rep ( j, i, i + stp - 1 ) {
adf( u[j + stp], u[j] );
}
}
}
}
int main() {
scanf( "%d %d", &n, &m );
rep ( i, 0, n - 1 ) scanf( "%d", &a[i] );
rep ( i, 0, m - 1 ) scanf( "%d", &b[i] );
rep ( i, 0, n - 1 ) {
rep ( j, 0, m - 1 ) {
int t; scanf( "%d", &t );
adj[j] |= t << i;
}
}
rep ( i, 0, m - 1 ) sum[adj[i]] += b[i];
fwtOR( 1 << n, sum, []( int& u, const int v ) { u += v; } );
int tak = 1e9;
rep ( S, 1, ( 1 << n ) - 1 ) {
rep ( i, 0, n - 1 ) if ( S >> i & 1 ) tot[S] += a[i];
if ( sum[S] ) chkmin( tak, tot[S] + 1 - sum[S] );
}
if ( tak <= 0 ) return puts( "0 1" ), 0;
printf( "%d ", tak );
int way = 0; init( tot[( 1 << n ) - 1] );
rep ( S, 1, ( 1 << n ) - 1 ) {
cvr[S] = tot[S] + 1 - sum[S] == tak;
chs[S] = comb( tot[S], tak );
if ( __builtin_popcount( S ) & 1 ) chs[S] = sub( 0, chs[S] );
}
fwtAND( 1 << n, cvr, []( int& u, const int v ) { u += v; } );
fwtOR( 1 << n, chs, addeq );
rep ( S, 1, ( 1 << n ) - 1 ) if ( cvr[S] ) {
( __builtin_popcount( S ) & 1 ? subeq : addeq )( way, chs[S] );
}
printf( "%d\n", way );
return 0;
}
\(\mathcal{Details}\)
某个问题无法找到解决方法时,尤其是在速度相关的比赛时,一定要冷静下来,形式地描述“我想要求什么东西”,而不是对着代码修修补补。
Solution -「ABC 215H」Cabbage Master的更多相关文章
- Solution -「ABC 219H」Candles
\(\mathcal{Description}\) Link. 有 \(n\) 支蜡烛,第 \(i\) 支的坐标为 \(x_i\),初始长度为 \(a_i\),每单位时间燃烧变短 \(1\) ...
- Solution -「ABC 213G」Connectivity 2
\(\mathcal{Description}\) Link. 给定简单无向图 \(G=(V,E)\),点的编号从 \(1\) 到 \(|V|=n\).对于 \(k=2..n\),求 \(H= ...
- Solution -「ABC 213H」Stroll
\(\mathcal{Description}\) Link. 给定一个含 \(n\) 个结点 \(m\) 条边的简单无向图,每条边的边权是一个常数项为 \(0\) 的 \(T\) 次多项式, ...
- Solution -「ABC 217」题解
D - Cutting Woods 记录每一个切割点,每次求前驱后驱就好了,注意简单判断一下开闭区间. 考场上采用的 FHQ_Treap 无脑莽. #include <cstdio> #i ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution Set -「ABC 217」
大家好屑兔子又来啦! [A - Lexicographic Order] 说个笑话,\(\color{black}{\text{W}}\color{red}{\text{alkingDead} ...
- Solution -「ARC 110E」Shorten ABC
\(\mathcal{Description}\) Link. 给定长度为 \(n\),包含 A, B, C 三种字符的字符串 \(S\),定义一次操作为将其中相邻两个不相同的字符替换为字符集 ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
随机推荐
- spring controller获取web前端post数据乱码解决
web.xml文件加上如下代码<!-- post请求乱码拦截器 --><filter> <filter-name>CharacterEncodingFilter&l ...
- Leetcode算法系列(链表)之两数相加
Leetcode算法系列(链表)之两数相加 难度:中等给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果,我们将 ...
- ON UPDATE CURRENT_TIMESTAMP请慎用
大家好,我是架构摆渡人.这是实践经验系列的第七篇文章,这个系列会给大家分享很多在实际工作中有用的经验,如果有收获,还请分享给更多的朋友. 今天给大家分享一个容易忽略的问题,正是因为容易忽略,所以才要重 ...
- Nginx日志通过Flume导入到HDFS中
关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新) flume上传到hdfs: 当我们的数据量比较大时,比如每天的日志文件达到5G以上 使用ha ...
- Windows系统上搭建Clickhouse开发环境
Windows系统上搭建Clickhouse开发环境 总体思路 微软的开发IDE是很棒的,有两种:Visual Studio 和 VS Code,一个重量级,一个轻量级.近年来VS Code越来越受欢 ...
- 使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101
本文要点:设计一条 Spring Boot 最基本的流水线:包括构建.制品上传.部署.使用 Docker 容器运行构建逻辑.自动化整个实验环境:包括 Jenkins 的配置,Jenkins agent ...
- Python与Javascript相互调用超详细讲解(2022年1月最新)(三)基本原理Part 3 - 通过C/C++联通
目录 TL; DR python调javascript javascript调python 原理 基于Node.js的javascript调用python 从Node调用python函数 V8 嵌入P ...
- day 10 删除空白字符
(1).有以下程序(大写变小写) (2).有以下程序,在[1]填写程序,使得程序正确运行. 分析:(*p)(int,int)是一个函数指针(一个指针[*p]指向的对象是一个函数),函数的形参是(int ...
- 链式printf()函数的用法
printf()函数:十进制格式型输出函数. #include <stdio.h> int printf( const char *format, ... ); 1.首先printf的返回 ...
- Cesium和Kaarta用高分辨率激光雷达可视化室内和地下环境
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Cesium使急救人员和军事操作人员更容易快速评估和了解密集和不 ...