杭电 bestcoder#18 Bits Problem

Problem Description
If the quantity of '1' in a number's binary digits is n, we call this number a n-onebit number. For instance, 8(1000) is a 1-onebit number, and 5(101) is a 2-onebit number. Now give you a number - n, please figure out the sum of n-onebit number belong to [0, R).
 

Input
Multiple test cases(less than 65). For each test case, there will only 1 line contains a non-negative integer n and a positive integer  R(n1000,0<R<21000) , R is represented by binary digits, the data guarantee that there is no leading zeros.
 

Output
For each test case, print the answer module 1000000007 in one line.
 

Sample Input
      
      
1 1000
 

Sample Output
      
      
7
 

Source


  比如13,1101,假设要求含3个1的个数,就等于紫色区域3个1的个数加上绿色区域2个1的个数加上紫色区域1个1的个数,如果这条路径本身满足则还要加1。


  先初始化,用f[i][j]表示高度为i的完全二叉树的数中二进制恰好有j个1的数的个数,则有f[i][j]=f[i-1][j]+f[i-1][j-1]。
  然后从31位循环到第1位(如果此时路径上的1已经超过要求就退出循环),用k表示目前已经路径上已经有几个1。如果这一位是1,就k++,并且把这一位变成0。如果下一位是1,就需要加上以这一位为根的左子树上满足k-K(K是题目要求的1)个1的个数。

这个题求得是所有数的和,如果当前位是1则要把跟他平级的左子树的所有情况的值都加上。

  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<string>  
  4. #include<cstring>  
  5. #include<vector>  
  6. #include<cmath>  
  7. #include<queue>  
  8. #include<stack>  
  9. #include<map>  
  10. #include<set>  
  11. #include<algorithm>  
  12. using namespace std;  
  13. typedef long long LL;  
  14. const int maxn=1010;  
  15. const int MOD=1000000007;  
  16. LL C[maxn][maxn],W[maxn];  
  17. int N;  
  18. char s[maxn];  
  19. void init()  
  20. {  
  21.     memset(C,0,sizeof(C));  
  22.     C[0][0]=C[1][0]=C[1][1]=1;  
  23.     for(int i=2;i<maxn;i++)  
  24.     {  
  25.         C[i][0]=C[i][i]=1;  
  26.         for(int j=1;j<i;j++)  
  27.             C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;  
  28.     }  
  29.     W[0]=1;  
  30.     for(int i=1;i<maxn;i++)  
  31.         W[i]=(W[i-1]*2)%MOD;  
  32. }  
  33. LL f(int len,int cnt)  
  34. {  
  35.     LL ans=0;  
  36.     if(len>=1&&cnt>=1)ans=(W[len]-1)*C[len-1][cn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值