2025.7.7 NOIP2025模拟赛1

T3:

题目大意:

给定一个大小为 \(N\),由 \(1 \sim N\) 构成的集合,现在问你能有多少种不同的子集,使得子集中任意两个值相与等于两数中一个数,要么为 01。
\(N \le 2^{5000}\),输入时给定二进制。
答案模 \(10^9 + 7\)

解题思路:

不难发现题目其实是一个集合套集合的形式,要求你统计子集,使得满足两两之间交集为空或包含。

先考虑他的简单形式:\(n = 2^k - 1\) 时。
这个时候我们发现我们不需要考虑这个子集或起来的 1 在哪些位置了,我们值i关心它的个数。
那么为了避免算重,我们考虑设 \(f_{i}\) 表示或起来恰好大小为 \(i\) 的方案数。
那么我们考虑枚举包含第一个 1 的最大的数是几个 1 的。
但有个问题,就是如果我们通过 \(f\) 算的话,必须得 \(O(n^3)\) 才行。

所以套路的,我们再设一个 \(g\),表示或起来不超过 \(i\) 的方案数,但不能选大小为 \(i\) 的集合。
那么考虑如何转移 g。

还是考虑第一个 1 是在一个大小为多少的数中,当然也有可能第一个 1 不出现。
那么

\[g_{i} = \sum_{j = 0}^{i - 1} f_{j} + \sum_{j = 0}^{i - 2} g_{j + 1} \times \binom{i - 1}{j} \times \sum_{k = 0}^{i - 1 - j} g_{k} \]

\[f_{i} = g_{i} + \sum_{j = 0}^{i - 2} \binom{i - 1}{j} \times g_{j + 1} \times f_{i - 1 - j} \]

答案就是 \(\sum_{i = 1}^{n} f_{i}\)
那么我们就能做完 \(N = 2^k - 1\) 了。

然后考虑一般形式。
先分讨一下在最终的子集里最高位的 1 存不存在。
若不存在,那么 \(2 \sim n\) 位没有要求,是 \(\sum_{i = 1}^{n - 1} f_{i}\)
若存在,那么和上面一样,枚举与第一个 1 在一起的 1 的个数。
那么还得预处理出 \(2^k \sim n\) 中对于每个 i 有多少数的二进制中有 i 个 1。

然后这部分答案是 \(\sum_{i = 1}^{n} cnt_{i} \times g_{i} \times \sum_{j = 0}^{n - i} f_{j}\)
那么最终时间复杂度为 \(O(n^2)\)

其实这道数数主要是难在一些不重不漏的二进制的计数技巧,比如:

  1. f 的定义中强定或起来为 i 个,g 中不强定。
  2. 枚举第一位与哪些位在一起,这个在状压中也经常出现。

T4:

题目大意:

有一个长度为 \(n\) 的排列,现在确定了前 \(k\) 个位置,让你将后 \(n - k\) 个位置填了,使得 \(i\) 不在 \(i - 1\)\(i + 1\) 中间。
求方案数,答案模 \(10^9 + 7\)
\(n \le 5000\)

解题思路:

首先我们发现假设 1 和 2 的相对位置定了,那么所有都定了。

于是我们可以套路的类似插入地记录 dp 状态。
\(dp_{i, j, 0/1}\) 表示考虑前 \(i\) 个数,且第 \(i\) 个数相对位置是在第 \(j\) 个位置,且 \(i - 1\)\(i\) 的前/后的方案数。
为了方便,我们可以强定初始时是 \(1 \sim k\) 这些位置。

然后直接暴力转移是 \(O(n^3)\) 的,可以拿差分优化一下。
这个题能这么做其实是很特殊的,因为转移时只有 \(i\) 以及 \(i - 1\)\(i\) 的关系才能影响 \(i + 1\)
感觉 dp 状态变成动态插入后也是更方便写了。
因为我们如果记录在最后的位置的话,我们不好记录哪些位置被填了。

posted @ 2025-07-07 23:23  positive_deviation  阅读(22)  评论(0)    收藏  举报