Description
给定一个 $n \times m$ 的网格,每个格子的权值为 $a_{i,j}$,现在要从 $(1,1)$ 走到 $(n,m)$,求异或和等于 $k$ 的路径数。
$(1 \leq n,m \leq 20,0 \leq a_{i,j},k \leq 10^{18})$
Source
Solution
$n,m$ 的范围很小,所以考虑搜索。
直接暴搜显然不行,因为路径数很多。
所以使用 折半搜索 。
从起点和终点开始分别搜索,搜到对角线停止,设路径总数为 $k$,则时间复杂度可以降为 $O(\sqrt k)$ 。
起点开始只能向下或向右走,终点开始只能向上或向左走,注意边界。
我们可以开一个 $\rm map$ 存下从 $(1,1)$ 到对角线上的点 $(x,y)$ 异或和为 $val$ 的路径数。第二次搜到 $(x,y)$ 时,若当前异或和为 $val$,则答案需要加上从 $(1,1)$ 到 $(x,y)$ 异或和为 $k \oplus val$ 的路径数($\oplus$ 表示异或,异或的逆运算也是异或)。
怎么判断 $(x,y)$ 是否在对角线上?只要看 $x+y$ 是否与 $\left \lfloor \frac{n + m}{2} \right \rfloor + 1$ 相等即可(对角线是一次函数)。至于为什么 $+1$,是因为能够防止 $n = m = 1$ 的情况出错。
Code
1 |
|