数位DP
将一个数写成二进制,如果0的个数>=1的个数,那么这就是一个round number
问两个数之间有多少个round number
直接按二进制来数位DP,d[len][num_0][num_1]保存len位,0个数为num_0,1个数为num_1的round number个数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=32;
int d[N][N][N];
int dis[N];
int dp(int len,int num_0,int num_1,bool flag)
{
if(len==-1) return num_0>=num_1;
if(!flag&&d[len][num_0][num_1]!=-1) return d[len][num_0][num_1];
int ans=0;
int end=flag?dis[len]:1;
for(int i=0;i<=end;i++)
{
ans+=dp(len-1,num_0+(i==0&&num_1),num_1+(i==1),flag&&i==end);
}
if(!flag) d[len][num_0][num_1]=ans;
return ans;
}
int solve(int n)
{
int t=0;
while(n)
{
dis[t++]=n%2;
n/=2;
}
return dp(t-1,0,0,true);
}
int main()
{
memset(d,-1,sizeof(d));
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",solve(r)-solve(l-1));
return 0;
}