Jerry 最近在研究异或运算,异或也叫半加运算,其运算法则相当于不带进位的二进制加法。Jerry 给你一个数字 N,他想知道在 0 到N之间有多少对数字 (a,b) 满足 u+v=a,u ⊕ v=b, ⊕表示按位异或,由于答案将会非常大,请将结果对 1e9+7 取模。输入一个整数N(0<=N<1e18)输出整数对 (a,b) 的数目,结果模1e9+7
由于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
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。