下文的
⌈操作
⌋ 表示将集合
A 变成
Ultra(A)。
先考虑如何求出
A 的 mex-limit,我们观察一些性质。
性质一:若存在
i∈[0,2k−1] 使得
i∈/A,则无论经过多少次操作,都有
mex(A)<2k。
于是我们可以将
A 中
≥2k 的数删去,不影响 mex-limit。
性质二:设
k 为满足
∀i∈[0,2k−1],i∈A 的最大的
k,若
2k∈A,则我们令
A←{i−2k∣2k≤i∧i∈A},不影响 mex-limit。
证明:我们发现一次操作后,
A 中所有数的二进制下第
k 位都发生了变化,且此时
[0,2k−1] 没有被填满,因此我们可以删掉操作后
[2k,2k+1−1] 的部分,即操作前
[0,2k−1] 的部分。
性质三:设
k 为满足
∀i∈[0,2k−1],i∈A 的最大的
k,若
2k∈/A 且
(2k+1−1)∈A,则我们可以令
A←{i⊕(2k+1−1)∣2k≤i∧i∈A},不影响 mex-limit。
证明:此时
mex(A)−1=2k−1,故操作一次后
2k+1−1 就变成了
2k,再利用性质二即可得证。
性质四:设
k 为满足
∀i∈[0,2k−1],i∈A 的最大的
k,若
2k∈/A 且
(2k+1−1)∈/A,则
A 的 mex-limit 为
2k。
性质五:任意集合都是 mex-stable 的,且 mex-limit 必定为
2 的幂。
有了这几个性质,我们就可以进行 DP 了,设
fw,c,i 表示我们在
[0,2w−1] 中选择
i 个不同的数,且
0 必须选择,得到集合的 mex-limit 为
2c 的方案数,转移如下:
-
设
k 为满足
∀i∈[0,2k−1],i∈A 的最大的
k,若
k≤w−2,则
[2w−1,2w−1] 中的数必定不会影响 mex-limit,我们从
fw−1,c,j 转移过来,系数是
(i−j2w−1)。
-
-
若
2w−1∈A,则根据性质二,我们从
fw−1,c,i−2w−1 转移过来。
-
若
2w−1∈/A,(2w−1)∈A,则根据前面的性质,此时我们发现若
[2w−1+2w−2,2w−1] 填满了,那么 mex-limit 还会递归到
[2w−1,2w−1+2w−2−1],因此我们需要设一个辅助 DP。
设
gw,c,i 表示在
[0,2w−1] 中选择
i 个不同的数,且
0 必须选择,
2w−1 必须不选择,得到集合的 mex-limit 为
2c 的方案数,则
fw,c,i 会从
gw−1,c,j 转移过来。
-
若
2w−1∈/A,(2w−1)∈/A,则根据性质四,此时 mex-limit 为
2w−1,方案数为
(i−2w−12w−1−2)。
-
g 的转移和
f 是类似的,注意
f 和
g 在转移时可能有一些边界情况。
若直接实现这个 DP,则时间复杂度是
O(22kpoly(k)) 级别的,注意到转移是卷积的形式,且模数
M 减去一后可以被
218 整除,故我们只需先求出
M 的原根,就可以用 NTT 优化转移的时间复杂度。
最后的时间复杂度是
O(∑i=0k2ii2)=O(2kk2) 的。