题目链接:http://poj.org/problem?id=3252
题意: 一个数的二进制表示中0的个数大于等于1的个数则称作Round Numbers。求区间[L,R]内的 Round Numbers的个数。
思路:
int c[N][N];
void init()
{
int i,j;
FOR0(i,N)
{
c[i][0]=c[i][i]=1;
for(j=1;j<i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
int n,m;
int b[N],num;
int cal(int n)
{
if(n<=1) return 0;
num=0;
while(n) b[num++]=n&1,n>>=1;
num--;
int ans=0,i,j,k;
for(i=num;i>=1;i--)
{
if(i&1)
{
k=i/2;
for(j=k+1;j<=k+k;j++) ans+=c[k+k][j];
}
else
{
k=i/2;
for(j=k;j<=k+k-1;j++) ans+=c[k+k-1][j];
}
}
int n0=0,n1=0;
for(i=0;i<=num;i++)
{
if(b[i]) n1++;
else n0++;
}
if(n1<=n0) ans++;
n0=0; n1=1;
for(i=num-1;i>=0;i--)
{
if(b[i]==0) n0++;
else
{
for(j=i;j>=0&&j+n0+1>=i-j+n1;j--) ans+=c[i][j];
n1++;
}
}
return ans;
}
int main()
{
init();
Rush(n)
{
RD(m);
PR(cal(m)-cal(n-1));
}
}