转化为二进制,进行dp,
记录的内容是在pos位上x个0、y个1情况下的有效数字个数,
pre消除前导0影响。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#define lint long long
using namespace std;
lint dp[33][33][33];
lint wei[50];
lint dfs(int pos,int num0,int limit,int pre,int num1)
{
if (pos==-1)
return num0>=num1;
lint ans=0;
if (!limit&&dp[pos][num0][num1]!=-1)
return dp[pos][num0][num1];
int up=limit?wei[pos]:1;
for(int i=0;i<=up;i++)
{
if(pre==1&&i==0)
ans+=dfs(pos-1,num0,limit&&i==up,1,num1);
else
ans+=dfs(pos-1,num0+(i==0),limit&&i==up,0,num1+(i==1));
}
if (!limit)
dp[pos][num0][num1]=ans;
return ans;
}
lint solve(lint num)
{
int i=0;
while(num)
{
wei[i]=num%2;
num/=2;
i++;
}
return dfs(i-1,0,1,1,0);
}
int main()
{
lint i,j,l,n,m,t,k;
memset(dp,-1,sizeof dp);
scanf("%lld%lld",&m,&n);
printf("%lld\n",solve(n)-solve(m-1));
return 0;
}
来源:CSDN
作者:监心司
链接:https://blog.csdn.net/weixin_43840511/article/details/104246534