【做题记录】ARC096E Everything on It
-
\(\text{[ARC096E]\ Everything\ on\ It}\)
- 算法:容斥、组合
题目:
对于集合 \(\{1,2,\dots,n\}\),求它的子集族中,有多少个满足:
-
任意两个子集互不相同;
-
\(1,2,\dots,n\) 都在其中至少出现了 \(2\) 次。
答案对 \(M\) 取模。
\(2\le n\le 3000,10^8\le M\le10^9+9,M\in \text{prime}\)
题解:
采用容斥。
钦定 \(i\) 个数出现 \(\le1\) 次,不妨设为 \(1\to i\)
分两类。
- 不含 \(1\to i\)
很简单,即 \(n-i\) 个数字没有第二种限制,随便放,故有 \(2^{n-i}\) 中子集,加上每个子集要么选要么不选,所以共 \(2^{2^{n-i}}\) 种。
- 含有 \(1\to i\) 至少一次
枚举 \(k\) 表示其个数,
将 \(i\) 个数分入 \(k\) 个集合,但这和斯特林数不太一样,因为有的数可以不分,所以相当于是将那些出现 \(1\) 次的分到 \(k\) 个集合中去。
对于每个集合,只需满足至少出现一次的 \(1\to i\) ,其余 \(\ge i\) 的可有可无。
所以就是 \(i\) 个数分入 \(k\) 个集合的方案数,就是 \({(2^{n-i})}^k\)(因为有 \(k\) 个集合)
但题中 \(i\) 个数不一定要全放完,这难以处理,所以我们直接强行让它放完,那么我们可以在 \(k\) 个集合后面在新建一个集合(垃圾堆),这里面把那些没选的数往里面丢。
但这样有两个问题。一是我放完后无法分辨哪个是新增的垃圾堆哪个是原来的 \(k\) 个集合。二是我有可能放完 \(k\) 个集合后没有东西可往垃圾堆里丢了。
此时我们可以考虑分类。
第一种就是此时没有剩余可以丢进垃圾堆了,所以就只是单纯地 \(i\) 个数分入 \(k\) 个集合,即 \(\begin{Bmatrix}i\\k\end{Bmatrix}\) 种。
第二种就是还有可以往垃圾堆丢的,那么此时的垃圾堆其实可以看成也是一个普通的堆,那么就是 \(i\) 个数往 \(k\) 个集合里放,一共有 \(\begin{Bmatrix}i\\k+1\end{Bmatrix}\) 种。然后因为我们将垃圾堆看成普通的堆,所以我么还要从 \(k+1\) 个堆中选一个当垃圾堆,故还要再乘上 \(k+1\)。
所以总方案就是 \(\begin{Bmatrix}i\\k\end{Bmatrix}+(k+1)\begin{Bmatrix}i\\k+1\end{Bmatrix}=\begin{Bmatrix}i+1\\k+1\end{Bmatrix}\)
我们不妨假设 \(S(i)\) 表示 \(1\to i\) 没有出现。
所以答案就是先枚举 \(i\),然后乘上 \(F(i)\) 即组合数即可。
即
而 \(S(i)\) 即为第一种情况乘上第二种情况,
总的时间复杂度 \(O(n^2)\)。