poj 3252

时间:2023-03-09 04:22:10
poj 3252
http://poj.org/problem?id=3252
//自己搞了很长时间。。。现在刚刚有点明白。。
1 #include <iostream> using namespace std;
long long c[][];
void init(){
for(int i=;i<;i++){//初始化组合数利用的是公式
c[i][] = c[i][i] = ;
for(int j=;j<i;j++)
c[i][j] = c[i-][j]+c[i-][j-];//公式
}
}
int mx(int a,int b){
if(a>b)
return a;
return b;
}
long long solve(long long n){
int len=;
int bit[];
while(n){//得到二进制数1--len
bit[++len] = n%;
n = n/;
}
long long sum = ;
for(int i=;i<len;i++){//当长度小于len时
for(int j=(i+)/;j<i;j++)
sum += c[i-][j];
}
//长度等于len时
int one = ;
int zero =;
for(int i=len-;i;i--){
if(bit[i]){//如果在这一位是1则将其其改为0,那么得到的数一定比原来的数小,再枚举。。
zero ++;//改为0后。。0的数目加1,一的数目不变
for(int j = mx(,(len+)/-zero);j<i;j++)
sum += c[i-][j];
zero--;//用完后改归来,0的数目-1,1的数目+1;
one++;
}
else //这一位是0, 那么就将0的数目加1
zero++;
}
return sum;
}
int main()
{
init();
long long a,b;
while(cin>>a>>b){ //[a,b]=[0,b+1)-[0,a),所以此处就应该应该这么写
cout<<solve(b+)-solve(a)<<endl;
}
return ;
}