询问[a,b]内二进制表示中0的个数不小于1的个数的整数数量。
显然是数位dp。
最大的b有30位。当1的数量超过b的位数的一半的时候就无解了。
注意处理好前导0。
小心不要给数组下标为负的地方存东西。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
using namespace std;
int n,m;
int bit[35];
int F[35][70];
int dfs(int pos, int state, bool lead, bool limit) {
if(!pos) return state >= 35;
if(!lead && !limit && F[pos][state] != -1) return F[pos][state];
int ret = 0, up = limit ? bit[pos] : 1;
for(int i = 0; i <= up; ++i) {
ret += dfs(pos - 1, state + ( (i == 1) ? -1 : (lead ? 0 : 1) ), lead && i == 0, limit && i == up);
}
if(!lead && !limit) F[pos][state] = ret;
return ret;
}
int solve(int x) {
bit[0] = 0;
while(x) {
bit[++bit[0]] = x & 1;
x >>= 1;
}
return dfs(bit[0], 35, true, true);
}
int main() {
memset( F, -1, sizeof(F) );
scanf("%d%d", &n, &m);
printf( "%d", solve(m) - solve(n - 1) );
return 0;
}