\(\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\) 的并,则合法条件为

\[\forall S\subseteq B,~\sum_{b\in S}b\le\sum_{a\in\operatorname{adj}(S)}a
\]

那么可以得知非法条件。固定 \(\operatorname{adj}(S)\),显然 \(b\) 能多选就多选,最终能得到最小取球数量为

\[c=\max\left\{0,\min_{\operatorname{adj}(S)}\left\{\sum_{a\in\operatorname{adj}(S)}a-\sum_{\operatorname{adj}(\{b\})\subseteq\operatorname{adj}(S)}b+1\right\}\right\}.
\]

  令集族 \(\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\}\),也能避免算重地求出方案数为:

\[\sum_{T\subseteq A}[\exist S\in \mathcal S,~T\subseteq S]f(T,c).
\]

其中 \(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的更多相关文章

  1. Solution -「ABC 219H」Candles

    \(\mathcal{Description}\)   Link.   有 \(n\) 支蜡烛,第 \(i\) 支的坐标为 \(x_i\),初始长度为 \(a_i\),每单位时间燃烧变短 \(1\) ...

  2. Solution -「ABC 213G」Connectivity 2

    \(\mathcal{Description}\)   Link.   给定简单无向图 \(G=(V,E)\),点的编号从 \(1\) 到 \(|V|=n\).对于 \(k=2..n\),求 \(H= ...

  3. Solution -「ABC 213H」Stroll

    \(\mathcal{Description}\)   Link.   给定一个含 \(n\) 个结点 \(m\) 条边的简单无向图,每条边的边权是一个常数项为 \(0\) 的 \(T\) 次多项式, ...

  4. Solution -「ABC 217」题解

    D - Cutting Woods 记录每一个切割点,每次求前驱后驱就好了,注意简单判断一下开闭区间. 考场上采用的 FHQ_Treap 无脑莽. #include <cstdio> #i ...

  5. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  6. Solution Set -「ABC 217」

      大家好屑兔子又来啦! [A - Lexicographic Order]   说个笑话,\(\color{black}{\text{W}}\color{red}{\text{alkingDead} ...

  7. Solution -「ARC 110E」Shorten ABC

    \(\mathcal{Description}\)   Link.   给定长度为 \(n\),包含 A, B, C 三种字符的字符串 \(S\),定义一次操作为将其中相邻两个不相同的字符替换为字符集 ...

  8. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  9. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

随机推荐

  1. nuxt创建项目

    1.使用 npm 安装 npm install -g vue-cli 2.安装nuxt项目 vue init nuxt-community/koa-template 项目名称 3.如果 vue-cli ...

  2. 用户注册调优 及Connection对象

    调优的方法: (1)减少Connection对象的销毁与创建 我们可以在服务器启动时 预先创建好二十个Connection对象 因为每次Coonection对象的创建与销毁会浪费大量的时间  我们需要 ...

  3. 【golang学习记录】环境搭建

    [golang学习记录]环境搭建 一. 概述 本文是[golang学习记录]系列文章的第一篇,安装Go语言及搭建Go语言开发环境,接下来将详细记录自己学习 go 语言的过程,一方面是为了巩固自己学到的 ...

  4. 【记录一个问题】cv::cuda::BufferPool发生assert错误

    cv::cuda::setBufferPoolUsage(true); const int width = 512; const int height = 848; const int channel ...

  5. WebGPU相关的资源学习和社区

    我在网上搜寻了很多关于WebGPU相关的资料: #我觉得首先在B站上看到的徐博士免费教程非常好,讲解详细,并且评论回复比较快,都会有回应,徐博士B站网址:https://space.bilibili. ...

  6. grpc基础讲解和golang实现grpc通信小案例

    grpc简介 gRPC由google开发,是一款语言中立.平台中立.开源的远程过程调用系统 gRPC客户端和服务端可以在多种环境中运行和交互,例如用java写一个服务端,可以用go语言写客户端调用 g ...

  7. golang中的channel

    1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...

  8. golang中字符串的底层实现原理和常见功能

    1. 字符串的底层实现原理 package main import ( "fmt" "strconv" "unicode/utf8" ) f ...

  9. java-导入import

    1 package face_package; 2 3 import face_packagedemoA.DemoA; 4 import face_packagedemoB.DemoB; 5 //真正 ...

  10. 003Linux查看文件内容的5个命令姿势

    01 开篇 Linux 中查看文件内容常用的有如下 5 个命令: cat: more: less: tail: head. 02依次看看这些命令的使用姿势 cat 一次性将所有内容输出到屏幕上,方便查 ...