这题虽然说是组合数学但是锻炼数位dp的思想是挺有帮组的的
参考大牛博客:http://hi.baidu.com/lxyzmnwvhokptur/item/33ddd66a3b9c8699c5d24919
比较难理解的一题
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
typedef long long lld;
#define oo 0x3f3f3f3f
#define maxn 100+5
int bit[maxn];
lld C[maxn][maxn];
void GetC()
{
C[0][0]=1;
for(int i=1;i<30;i++)
{
C[i][0]=C[i][i]=1;
for(int j=1;j<i;j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
lld Sum(int x)
{
int len=0;
while(x)
{
bit[++len]=x%2;
x/=2;
}
lld ans=0;
//计算小与len的数满足条件的个数
for(int i=1;i<=len-2;i++)//对下一位进行操作所以要-1,但又是求与长度的数所以在-1,于是就是-2
for(int j=i/2+1;j<=i;j++)
ans+=C[i][j];
int zero=0;
//计算等于len的数满足条件的个数
for(int i=len-1;i>=1;i--)
{
if(bit[i])
{
for(int j=(len+1)/2-(zero+1);j<=i-1;j++)//有多少个0减去多少个0,有0的话排列中0的个数就可以减少
ans+=C[i-1][j];
}
else zero++;
}
return ans;
}
int main()
{
GetC();
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
{
cout<<Sum(b+1)-Sum(a)<<endl;
}
return 0;
}