iefnah06

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

URL

https://codeforces.com/contest/1326/problem/F2

解法

对于长度为 \(N-1\) 的二进制串 \(s\),先算出 \(f(s)\) 表示为 \(1\) 的位置必定有边,为 \(0\) 的位置可能有边的方案数。原问题的答案可以通过容斥算出。

注意到 \(f(s)\) 的值只与 \(s\)\(1\) 的所有连续段长度形成的多重集有关,而 \(n=18\) 时不同的多重集只有 \(385\) 个(A000041),可以对每个多重集算 \(f(s)\)。记这个多重集内的段长度为 \(a_1,a_2,\ldots,a_k\:(a_1+a_2+\ldots+a_k=N)\),那么

\[f(s)=\sum_{\forall 1 \le i \le k,|m_i|=a_i}\prod_{i=1}^{k}g(m_i) \]

其中 \(g(m)\) 是用 \(m\) 集合内的人形成链的方案数,且所有 \(m\) 或起来是全集。直接暴力算是 \(O(3^N)\) 的。

继续优化,我们想要让每一个人都恰好被一个 \(m_i\) 包括,这个可以继续容斥。考虑记 \(g(l,m)\) 为用 \(m\) 的一个子集形成长度为 \(l\) 的链的方案数,那么

\[f(s) = \sum_{t \subset s}(-1)^{N-|t|}\prod_{i=1}^{k}g(a_i,t) \]

这样就不用子集 DP 了。

实现

https://ideone.com/jBqLrZ

posted on 2020-04-04 20:46  iefnah06  阅读(158)  评论(0)    收藏  举报