ABC050D/ARC066D Xor Sum

匆匆过客 提交于 2019-12-02 14:58:44

题目链接

题目大意

可表为 $(a \xor b, a + b)$ 的二元组有多少个?
$a, b$ 满足下列约束条件:
① $a, b$ 是非负整数;
② $a + b \le N$,$N$ 是给定的正整数且 $N \le 10^{18}$ 。

我的思考

考虑 $a \xor b$ 的二进制表示,对其进行数位 DP。
问题转化成

$ 0 \le x < 2^k $
$ 0 \le y < 2^k $
$ x + y \le M$
$k, M$ 给定且 $ 2^k \le M < 2^{k + 1}$ 。
二元组 $(x \xor y, x + y)$ 有多少种不同取值?

这个问题并不容易,思路至此中断。

参考题解

https://blog.csdn.net/just_sort/article/details/54288233

Key observation
可以给 $a, b$ 增加一个约束而不改变原题目的解:
③ $a$ 的每个二进制位都不大于 $b$ 的对应二进制位。

在这三条约束下,可以证明 $(a, b) \mapsto (a \xor b, a + b)$ 是单射。

证明:设 $(a_1, b_1) \ne (a_2, b_2)$ 。若 $a_1 \xor b_1 = a_2 \xor b_2$ 则必有某个二进制位,在此位上某一组的值是 $(0,0)$,另一组的值是 $(1, 1)$ 。考虑满足此条件的最高位,易见 $a_1+ b_1 \ne a_2 + b_2$ 。证毕。

至此问题化为在上述三个约束下,满足 $a + b \le N$ 的二元组 $(a, b)$ 有多少个?

令 $f(N)$ 表示所求,考虑 $a, b$ 的最低位(即权重为 $2^0$ 的位),$a, b$ 在此位上的取值有三种情况:$(0, 0)$、$(0, 1)$、$(1, 1)$;得到递推

$$ f(N) = f(N / 2) + f((N - 1) / 2) + f( (N - 2) / 2) $$

边界条件:
$ f(0) = 1, f(1) = 2 $

问题:算出 $f(N)$ 需要计算多少个状态?

据说状态数在 $(\log N)^2$ 的级别,我不能证明。

另一种 DP

仍按上述思路,下面介绍官方题解给出的 DP 方法。这种方法的复杂度比较清楚,并且其思想可以用于求解更为一般的数位 DP 问题。

令 dp[i][ j] 表示 $a + b$ 的二进制表示最高的 $i$ 位已经确定且不考虑 $i$ 以下的位,$a + b$ 的最高的 $i$ 位(换言之,$a + b$ 已经确定的部分)与 $N$ 的最高的 $i$ 位的差是 $j$ 的方案有多少种。

举例言之,N = 10101。a + b = 1**** 属于状态 dp[0][0],1 - 1 = 0,符号 * 表示暂不这些位上的值;a + b = 0**** 属于状态 dp[0][1],1 - 0 = 1;a + b = 00*** 属于状态 dp[1][2],10 - 00 = 2;a + b = 10*** 属于状态 dp[1][0],10 - 10 = 0;a + b = 100** 属于状态 dp[2][1],101 - 100 = 1;000** 属于状态 dp[2][5],101 - 000 = 5。

注意到当 $j \ge 2$ 时,$a + b$ 的 $i$ 以下的位可以任意选取。所以 $j \ge 2$ 的状态可以用 $j = 2$ 表示,因此 $j$ 可以只取 $0, 1, 2$ 这三个值。另外,由于只有 $j = 0, 1$ 的状态需要转移,在编程实现时,dp 数组的第二维取 2 即可。

转移方式

只有 dp[i][0] 和 dp[i][1] 需要转移;看 $N$ 的二进制第 $i+1$ 位上是多少,枚举 $a, b$ 的二进制第 $i + 1$ 位。

(1)$N$ 的第 $i + 1$ 位上是 0
dp[i][0] -- (0, 0) --> dp[i + 1][0]
dp[i][1] -- (0, 0) --> dp[i + 1][2]
dp[i][1] -- (0, 1) --> dp[i + 1][1]
dp[i][1] -- (1, 1) --> dp[i + 1][0]
(2)$N$ 的第 $i + 1$ 位上是 1
dp[i][0] -- (0, 0) --> dp[i + 1][1]
dp[i][0] -- (0, 1) --> dp[i + 1][0]
dp[i][1] -- (0, 0) --> dp[i + 1][2]
dp[i][1] -- (0, 1) --> dp[i + 1][2]
dp[i][1] -- (1, 1) --> dp[i + 1][1]

边界条件

由于 $N > 0$,$N$ 的二进制最高位一定是 1,故边界条件为 dp[0][0] = 1, dp[0][1] = 1。

复杂度

时间复杂度 $O(\log N)$,空间复杂度 $O(\log N)$ 。

References

https://qiita.com/259_Momone/items/86e90d17e4efe3b22433

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!