(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
题意:传送门
原题目描述在最下面。
求区间[a, b] (1e18)内有多少个数字的二进制位恰好有一个0。
思路:
请看如下式子:
100 - 1 = 11
11 - 1 = 10
1000 - 1 = 111
111 - 1 = 110
111 - 10 = 101
10000 - 1 = 1111
1111 - 1 = 1110
1111 - 10 = 1101
1111 - 100 = 1011
可以看出来对于一个二进制位只有一个0的数字 x ,有如下特点:
x = (1<< i) - 1 - (1 << j)
然后枚举就可以了。
AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <bitset>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;
LL n, m;
int main(){
while(~scanf("%lld%lld", &n, &m)){
LL ans = 0;
for(int i = 2; i <= 63; ++i){
for(int j = 0; j < i-1; ++j){
LL tmp=(1LL<<i)-1-(1LL<<j);
if(tmp>=n&&tmp<=m)ans++;
}
}
printf("%lld\n", ans);
}
return 0;
}