题意:计算区间 l 到 r 中的 round number 数,round number 定义为二进制形式下0的个数不少于1的个数的数。
分析:我开的状态比较麻烦f[i][j][k][l] i 表示i位,j表示是0多还是1多,k表示多多少,l表示有没有前导零。
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll a, b;
ll s[50];
ll dp[50][2][50][2];
ll dfs(int pos, ll oz, ll num, int lim, int fl){
if(pos < 1) {
return !oz || num == 0;
}
if(!lim && dp[pos][oz][num][fl] != -1){
return dp[pos][oz][num][fl];
}
int end = lim ? s[pos] : 1;
ll ret = 0;
for(int i = 0; i <= end; i++){
int nu = i == 0 ? ((num == 0 || oz == 0) ? num+1 : num-1 ): ((num == 0 || oz == 1) ? num+1 : num-1);
int o = i == 0 ? num == 0 ? 0 : oz : num == 0 ? 1 : oz;
if(!fl && i == 0) ret += dfs(pos - 1, 0, 0, 0, 0);
else ret += dfs(pos - 1, o, nu, lim && (i == end), 1);
}
if(!lim){
dp[pos][oz][num][fl] = ret;
}
return ret;
}
ll solve(ll k){
int len = 0;
while(k){
s[++len] = k % 2;
k >>= 1;
}
return dfs(len, 0, 0, 1, 0);
}
int main(){
ll a, b;
memset(dp, -1, sizeof(dp));
while(~scanf("%lld%lld", &a, &b))
printf("%lld\n", solve(b) - solve(a - 1));
}