poj 3252

http://poj.org/problem?id=3252
//自己搞了很长时间。。。现在刚刚有点明白。。
1
#include <iostream> 2 3 using namespace std; 4 long long c[35][35]; 5 void init(){ 6 for(int i=0;i<33;i++){//初始化组合数利用的是公式 7 c[i][0] = c[i][i] = 1; 8 for(int j=1;j<i;j++) 9 c[i][j] = c[i-1][j]+c[i-1][j-1];//公式 10 } 11 } 12 int mx(int a,int b){ 13 if(a>b) 14 return a; 15 return b; 16 } 17 long long solve(long long n){ 18 int len=0; 19 int bit[35]; 20 while(n){//得到二进制数1--len 21 bit[++len] = n%2; 22 n = n/2; 23 } 24 long long sum = 0; 25 for(int i=1;i<len;i++){//当长度小于len时 26 for(int j=(i+1)/2;j<i;j++) 27 sum += c[i-1][j]; 28 } 29 //长度等于len时 30 int one = 1; 31 int zero =0; 32 for(int i=len-1;i;i--){ 33 if(bit[i]){//如果在这一位是1则将其其改为0,那么得到的数一定比原来的数小,再枚举。。 34 zero ++;//改为0后。。0的数目加1,一的数目不变 35 for(int j = mx(0,(len+1)/2-zero);j<i;j++) 36 sum += c[i-1][j]; 37 zero--;//用完后改归来,0的数目-1,1的数目+1; 38 one++; 39 } 40 else //这一位是0, 那么就将0的数目加1 41 zero++; 42 } 43 return sum; 44 } 45 int main() 46 { 47 init(); 48 long long a,b; 49 while(cin>>a>>b){ //[a,b]=[0,b+1)-[0,a),所以此处就应该应该这么写 50 cout<<solve(b+1)-solve(a)<<endl; 51 } 52 return 0; 53 }

 

posted @ 2013-07-16 18:51  夜晓楼  阅读(186)  评论(0编辑  收藏  举报