题目描述
大家都知道,异或的性质就相当于不带进位的二进制加法。
那么我们再稍微拓展一下,如果加法与异或在十进制中所产生的结果相同的话,会怎样呢?
给一个二进制数n,需要你找出一对非负整数x、y,使得它们符合下面的两个性质。
x+y<=n
x+y==x⊕y
那么问题来了,对于一个给定的n,能够有多少对符合条件的(x,y)呢?
结果对109+7取模。
思路
题目需要满足两个条件:x+y<=n;x+y==x⊕y
- x+y==x⊕y
首先,异或的运算法则为:相同为0,不同为1。异或可以看作为没有进位的加法。要满足这个条件,则x和y的二进制表现形式不能同时为1(同时为1 ,则相加会产生进位,不能和异或的运算结果保持相等)。所以,x和y只有三种情况{1,0},{0,1},{0,0}。 - x+y<=n
n是一个二进制数,所以只有1和0两种情况。
当n=1时,若x+y=n,则有两种情况。第一种:x=0,y=1;第二种:x=1,y=0。若x+y<n,也有两种情况。第一种:x+y的前i-1位小于n的前i-1位,则第i位x和y的三种情况均符合要求。第二种:x+y的前i-1位均与n的前i-1位相等,第i位,x=0,y=0。
当n=0时,若x+y=n,则第i位,x=0,y=0。若x+y<n,可以是x+y的前i-1位小于n的前i-1位,则第i位x和y的三种情况均符合要求。代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int main() {
string n;
cin >> n;
long long res = 1, cnt = 0;
for (long long i = 0; i < n.size(); i++) {
cnt = (cnt * 3) % mod;
if (n[i] == '1') {
cnt = (cnt + res) % mod;
res = (res * 2) % mod;
}
}
cout << (res + cnt) % mod;
return 0;
}