1 条题解
-
0
题目理解
我们有两个长度为 的二进制字符串 和 。定义一个 的网格,格子 的值为 (异或)。
从 出发,只能向下或向右移动。如果一条路径上所有格子值都为 ,则称为可行路径。
表示通过翻转 或 中的某些位(每次翻转一个位置),使得存在一条从 到 的可行路径的最少翻转次数。
求:
第一步:可达条件化简
当前在格子 时,,即 。
- 向下走到 :需要 ,即 。
结合 ,得 。 - 向右走到 :需要 ,即 。
结合 ,得 。
关键结论:
要能走到 ,必须满足:即前缀 全相等,前缀 全相等,且这两个值相同。
第二步: 的公式
设该公共值为 。
要达成这个状态:
- 对于 :如果 ,需要把其中所有 翻成 ;如果 ,需要把其中所有 翻成 。
- 对于 :同理。
令:
- 中 的个数
- 中 的个数
- 类似定义
则:
- 若选 :代价 =
- 若选 :代价 =
因此:
$$f(x,y) = \min\big(\text{ones}_a(x) + \text{ones}_b(y),\; \text{zeros}_a(x) + \text{zeros}_b(y)\big) $$
第三步:化简公式
注意:,。
设:
则:
$$f = \min(C_0, C_1) = \frac{C_0 + C_1}{2} - \frac{|C_0 - C_1|}{2} $$而 (因为每个位置都贡献一次 或 计数,总和就是总元素数)。
所以:
第四步:化简
$$C_0 - C_1 = \big(\text{zeros}_a(x) - \text{ones}_a(x)\big) + \big(\text{zeros}_b(y) - \text{ones}_b(y)\big) $$定义:
注意: 可正可负。
那么:
但是题解中用的是另一种定义(可能是为了对称性):
设:
- $\text{pre}_a(x) = \text{zeros}_a(x) - \text{ones}_a(x)$
- $\text{pre}_b(y) = \text{ones}_b(y) - \text{zeros}_b(y)$
则:
因此:
两种定义等价,只是符号变换。
第五步:求和
原和式:
$$\sum_{x=1}^n \sum_{y=1}^n f(x,y) = \sum_{x,y} \frac{x+y}{2} - \frac{1}{2} \sum_{x,y} |\text{pre}_a(x) - \text{pre}_b(y)| $$第一部分:
$$\sum_{x=1}^n \sum_{y=1}^n \frac{x+y}{2} = \frac{1}{2} \left( \sum_{x=1}^n \sum_{y=1}^n x + \sum_{x=1}^n \sum_{y=1}^n y \right) $$$$= \frac{1}{2} \left( n \cdot \frac{n(n+1)}{2} + n \cdot \frac{n(n+1)}{2} \right) = \frac{n^2(n+1)}{2} $$所以:
$$\text{ans} = \frac{n^2(n+1)}{2} - \frac{1}{2} \sum_{x=1}^n \sum_{y=1}^n |\text{pre}_a(x) - \text{pre}_b(y)| $$
第六步:计算
我们有两个数组 和 (值域在 内)。
要求:
经典做法:
- 对 和 排序。
- 用双指针或前缀和计算。
具体地,先统计 的频数分布(值域范围 ,可偏移到非负索引)。
对每个 :- 小于等于它的 值的个数记为 ,它们的和记为
- 贡献 = (这部分是 大于那些值的差)
- 加上另一部分:(这部分是 小于那些值的差)
总 可 或 计算。
题解中用了一种更巧妙的离线方法:
先计算前缀频数,然后对每个 用 查表,整体 。
第七步:最终算法
- 读入 。
- 计算 在 。
- 计算 在 。
- 将 值映射到 范围(加偏移 )。
- 用前缀和数组 统计 的频数和值的和。
- 对每个 ,用二分或直接查 计算 。
- 代入公式得到答案。
最终答案公式
$$\boxed{\text{ans} = \frac{n^2(n+1)}{2} - \frac{1}{2} \sum_{i=1}^n \sum_{j=1}^n |\text{pre}_a(i) - \text{pre}_b(j)|} $$其中:
时间复杂度 或 ,空间 。
- 向下走到 :需要 ,即 。
- 1
信息
- ID
- 7046
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者