1 条题解
-
0
1. 题意理解
我们有一个大数 ,它的二进制表示是字符串 重复 次得到的,且 的第一个字符是
1,所以 是一个很大的二进制数。我们要在 中选出 个不同的整数,使得它们的异或和为 ,问方案数。
- 顺序不重要(组合数)。
- ,且 。
- 最大 , 最大 。
2. 问题转化
设 ,那么 的二进制长度是 。
我们是在 中选数,也就是小于 的非负整数。
2.1 数位 DP 思路
这是一个典型的 数位 DP 问题,不过这里不是统计一个数,而是统计 个数的组合,并且要求它们异或和为 。
由于 很小(最大 7),我们可以用一个 DP 状态表示:
- 当前处理到二进制第几位(从高位到低位)
- 当前 个数在这一位之前与 的前缀的大小关系(是否已经小于 的对应前缀)
- 当前已确定部分的异或和(其实不需要记录完整异或和,因为只关心最终为 0)
但这里 个数是 不同的,并且是组合不是排列,所以我们需要考虑不同数的限制。
3. 关键难点
难点在于 是由 重复 次得到的,这提示我们可能要用 矩阵快速幂 或 自动机 + DP 来加速。
3.1 循环节性质
设 的长度为 ,那么 的二进制形式是 重复 次。
考虑从高到低处理二进制位,每 位是一个循环节(内容相同),但是注意:每个循环节内的位是固定的,由 给出。
3.2 逐块处理
我们可以把整个二进制串分成 块,每块长度 ,每块内的二进制模式相同。
定义状态:
- 当前块索引 (从 0 到 )
- 一个大小为 的向量,表示前面所有块中, 个数与 的大小关系(即是否已经小于 的对应前缀)以及当前块开始前的异或和的高位部分?
实际上更精确的模型是:
4. 自动机构建
我们考虑一个长度为 的二进制数 ,我们要选 个数 。
我们可以同时进行 个数的大小比较,用一个 位的状态 表示每个数目前是等于 的前缀(0)还是已经小于(1)。
同时,我们还需要记录当前所有已确定位的异或和(模 2),但这里长度很长,不能直接记录整个异或和。不过因为最终要求整个异或和为 0,我们可以逐位处理,并在最后检查。
4.1 逐位 DP
设 表示:
- 当前处理到位 (从高位到低位,总共有 位)
- : 位二进制,第 位为 1 表示 已经小于 的前缀,否则表示等于
- 当前已处理的所有位的异或和(0 或 1)
但这样状态数太大: 在 很大时不行。
5. 利用循环节
因为 是 重复 次,所以除了第一个块,后面的块模式相同。
我们可以先对 一个块(长度为 )进行预处理,计算转移矩阵:
- 输入:进入这个块时的 (大小关系状态)
- 输出:离开这个块后的新 ,以及在这个过程中,有多少种方法使得最终异或和为 0(或者我们只记录转移计数,最后再考虑异或和)
5.1 单块 DP
对于固定的一个 位块(即 ),我们做 DP:
设 表示在块内处理到第 位(0 到 ),当前大小关系状态是 ,当前块内已处理位的异或和为 的方案数。
转移时,枚举 个数在当前位的取值(0 或 1),但要满足大小关系约束:如果某个数之前是等于 的对应前缀,那么这一位不能大于 的这一位(即 );如果等于,则保持等于状态,如果小于,则可以任意取。
5.2 块间转移
一个块处理完后,输出的是新的 和这个块内异或和,但块与块之间的异或和是累加的(按位异或),所以我们需要记录块间的异或和吗?不行,因为最终只要总异或和为 0,中间过程可以任意。
实际上,我们可以把 异或和 0 的条件放到最后再检查,即我们只统计那些整个 位异或和为 0 的方案。
6. 最终解法框架
-
单块转移矩阵 表示:从进入块时大小状态 ,到离开块时大小状态 ,并且 不记录异或和(因为异或和是全局的,不能分块简单合并?这里需要处理)。
实际上,异或和是线性的(模 2),所以我们可以把异或和也作为状态的一部分在块间传递。但这样状态数是 ,仍然可行。
那么单块 DP 得到 表示:进入时 到离开时 的方案数。
-
整个 有 个块,第一个块可能特殊?不,所有块二进制模式相同,但第一个块进入时 (所有数都等于前缀),后面块进入时 可能非 0。
-
用矩阵快速幂把 个块的转移合并。
-
初始状态: 方案数 = 1。 最终状态: 的方案数总和。
7. 不同数的处理
我们还要保证 个数互不相同。这可以在单块 DP 中处理:在枚举当前位的取值时,如果两个数之前状态相同(都等于前缀)并且这一位取值相同,则它们仍然相同;如果某个数已经小于,则可以任意。我们要求最终所有数不能完全相同(即至少有一位不同),但题目要求严格不同,所以如果两个数在所有位都相等,则非法。
我们可以在最终统计时,去掉那些有重复数的方案。由于 很小,我们可以用容斥:先不管重复,最后减去有重复的情况。
8. 总结算法步骤
- 预处理单块转移矩阵 大小 ),即状态 到 。
- 用矩阵快速幂计算 。
- 初始向量 。
- 结果 = 中所有 的状态的和。
- 去掉选择中有重复数的情况(因为题目要求不同整数):用容斥,枚举哪些数相等,转化为选 个数的子问题,同样用上述 DP 但数的个数减少,递归或迭代计算。
- 1
信息
- ID
- 4781
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者