CF908E New Year and Entity Enumeration 题解
CF908E
给定 \(m\),令 \(M = 2^m -1\)。给定 \(\{0,1,\cdots, M\}\) 的大小为 \(n\) 的子集 \(T\),定义集合 \(T \subseteq S \subseteq \{0,1,\cdots,M\}\) 是好的当且仅当:
\(a \in S \Rightarrow a \oplus M \in S\)
\(a,b \in S \Rightarrow a\ and\ b \in S\)
求好的集合的个数
\(1 \leq m \leq 1000, 1 \leq n \leq min(2^m, 50)\)
-
我们先考虑假如得到了一个不完整的 \(S\) 如何把他变为合法的集合
-
打表找规律
-
可以发现当加入了
00011
和00111
后,他会把54
分成一部分,3
一部分,21
一部分,然后填0/1
,答案是: -
00000 00011 00100 00111 11000 11011 11100 11111
-
可以发现,若 \(S\) 中的 \(x_1,x_2,\cdots,x_t\) 位在所有数中要么同为 \(1\),要么同为 \(0\),也就是说相同,那么他们就会”打包“在一起,在 \(S\) 中独立取 \(0/1\)
-
其实这不是巧合,这是有依据的
-
第一条操作的意思显然就是 \(a \in S \Rightarrow (\sim a) \in S\)
-
而我们有:
-
\[\begin{align} & a\ or\ b = \sim((\sim a)\ and\ (\sim b)) \\ & a \oplus b = \sim((\sim(a\ or\ b)\ or\ (a\ and\ b)) \end{align} \]
-
因此上述的操作最终制造出了一个异或操作,即这些数构成了一个异或的线性基
-
因此我们只需要按位进行集合划分
-
设 \(dp_i\) 表示 \(i\) 位数,拆开 or 不拆开的所有方案数,有转移:
-
\[dp_i \leftarrow \sum_{j=0}^{i-1} \binom{i-1}{j} dp_{i-j-1} \]
-
大致意思是考虑第 \(i\) 位数和另外 \(i-1\) 个位置中 \(j\) 个位置划分成一个集合,然后继续递归
-
最后只需要根据乘法原理相乘即可
-
最终复杂度为 \(O(m^2+mn)\)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
2023-08-09 P5319 [BJOI2019] 奥术神杖
2023-08-09 P8019 [ONTAK2015] OR-XOR