开发者社区> 问答> 正文

遇见一个异或运算问题,求解答。

Jerry 最近在研究异或运算,异或也叫半加运算,其运算法则相当于不带进位的二进制加法。Jerry 给你一个数字 N,他想知道在 0 到N之间有多少对数字 (a,b) 满足 u+v=a,u ⊕ v=b, ⊕表示按位异或,由于答案将会非常大,请将结果对 1e9+7 取模。输入一个整数N(0<=N<1e18)输出整数对 (a,b) 的数目,结果模1e9+7

展开
收起
游客4skzfvnrxrzbi 2021-12-23 16:49:59 526 0
1 条回答
写回答
取消 提交回答
  • 由于u+v=a,u ⊕ v=b, 根据异或的性质我们可以知道:u+v =((u&v)<<1) +(u ⊕ v),所以 u+v >=u ⊕ v,那么只要 u+v<=n, u ⊕ v 也必定小于等于 n。于是这道题就转化成了对于 u+v<=n , 求 (u,v) 的对数。定义 dp[n] 表示 u+v<=n ,(u,v) 的对数,当 n=0 的时候 dp[0]= 1,n=1 时,dp[1]=2。他们的 (u,v) 分别是 {(0,0)} 和 {(0,0),(1,0)}。dp[n] 再往下递推的时候,要考虑 u+v<=n 时 二进制是如何由小到大转化过来的。从二进制上来看 u 和 v,两者的末位只有 0 或 1,那么二者的末位和有 0,1,2 三种情况。 设 u+v=x,令u= u12+u0,v=v12+v0u0+v0 即为二者的末位和,又有x<=n,故 (u1+v1)*2+u0+v0<=n, 所以u1+u2<=(n-u0-v0)/2。由u1+u2<=(n-u0-v0)/2 到 (u1+v1)*2+u0+v0<=n 可以推出来递推式:dp[n] =dp[n/2]+dp[(n-1)/2]+dp[(n-2)/2]。 因此:输入:3 输出:5

    2021-12-23 18:42:43
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载