题意:
以内有多少个数的二进制位里的数量大于的数量,数据范围

思路:
转为二进制,记忆化搜索二进制数,(写数位一定要看清参数,参数写反把自己搞蒙了,血亏)。
二进制的前导零是无效的,当前的长度、出现的次数以及出现的次数三个状态才能保证结果一样(写这么多题了我居然没加出现的次数这个状态)

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include <vector>
#include<map>
#include<set>
#include<utility>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7,maxm=2e5+7;
inline ll read() {
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57) {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
ll dp[35][35][35];
int digit[35];
ll dfs(int len,int cnt0,int cnt1,bool check,bool limit) {
    if(!len) {
        return cnt0>=cnt1;
    }
    if(!limit&&dp[len][cnt0][cnt1]!=-1) return dp[len][cnt0][cnt1];
    int endi=(limit?digit[len]:1);
    ll ans=dfs(len-1,cnt0+1*check,cnt1,check,limit&&0==endi);
    if(endi==1) ans+=dfs(len-1,cnt0,cnt1+1,true,limit);
    if(!limit) dp[len][cnt0][cnt1]=ans;
    return ans;
}
ll solve(ll x) {
    int len=0;
    while(x) {
        digit[++len]=x&1;
        x>>=1;
    }
    return dfs(len,0,0,false,true);
}
int main() {
    ll l,r;
    memset(dp,-1,sizeof dp);
    while(~scanf("%lld%lld",&l,&r)) {
        printf("%lld\n",solve(r)-solve(l-1));
    }
    return 0;
}