这题用组合数学来做,思路很好想,但是实现的时候细节台繁杂了,所以很容易出错。。
首先[a,b]可以看成[0,b+1)-[0,a)。
剩下的就用组合数学的知识很容易就能得出答案了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int C[35][35];
void init()
{
int i,j;
for (i=0; i<=31; i++)
{
C[i][0]=1;
C[0][i]=0;
}
C[0][0]=1;
for (i=1; i<=31; i++)
{
for (j=1; j<=31; j++)
{
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
//组合数公式:C(M-1,N-1)+C(M-1,N)=C(M,N)
}
int func(int n)
{
if (n == 0)
return 0;
int t,ln,i,j,ans,zn,m;
t=1;
ln=0;
ans=0;
while (t <= n)
{
++ln;
t<<=1;
if (ln == 31) //特别注意,不加这个会TLE T_T
break;
}
for (i=2; i<ln; ++i)
{
for (j=(i+1)/2; j<=i; ++j)
{
ans+=C[i-1][j];
}
}
t=1<<(ln-2);
zn=(ln+1)/2;
for (i=1; i<ln; ++i)
{
m=t&n;
if (m == t)
{
for (j=zn-1; j<ln-i; ++j)
{
ans+=C[ln-i-1][j];
}
}
else
{
--zn;
}
t>>=1;
}
return ans;
}
int main()
{
int a,b;
init();
scanf("%d%d",&a,&b);
printf("%d\n",func(b+1)-func(a));
}