题意:问给定区间内的数的二进制状态下0的个数大于等于1的个数的数量
思路:开两个变量记录0和1的个数即可,然后应该将数分解成二进制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=5010;
int dig[40];
ll dp[40][30][30];
ll dfs(int pos,int lim,int num0,int num1,int flag){
if(pos<0){
if(flag) return 0;
else if(num0>=num1) return 1;
else return 0;
}
if(!lim&&dp[pos][num0][num1]!=-1) return dp[pos][num0][num1];
int las=lim?dig[pos]:1;
ll ret=0;
for(int i=0;i<=las;i++){
if(flag&&i==0) ret+=dfs(pos-1,lim&&(i==las),0,0,1);
else if(i==0) ret+=dfs(pos-1,lim&&(i==las),num0+1,num1,0);
else ret+=dfs(pos-1,lim&&(i==las),num0,num1+1,0);
}
if(!lim) dp[pos][num0][num1]=ret;
return ret;
}
ll slove(ll n){
if(n==0) return 0;
int len=0;
while(n){
dig[len++]=n%2;
n/=2;
}
return dfs(len-1,1,0,0,1);
}
int main(){
memset(dp,-1,sizeof(dp));
ll n,m;
while(scanf("%I64d%I64d",&n,&m)!=-1){
printf("%I64d\n",slove(m)-slove(n-1));
}
return 0;
}