ural 1057 Amount of Degrees

题意:统计区间内t=B^n+.....+B^0,每项系数都为0或1,统计1的个数恰好为1的情况,这样的数有多少个

分析:看的刘聪的论文,分析很好,http://pan.baidu.com/s/1pL4FF4n,转化为统计二叉树上1的个数代码写的有点糙

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=55;
 4 typedef long long ll;
 5 ll f[maxn][maxn],d[maxn];
 6 int b,k;
 7 void init(){
 8     for(int i=0;i<=31;i++){
 9         f[i][0]=1;
10         for(int j=1;j<=i;j++)
11             f[i][j]=f[i-1][j]+f[i-1][j-1];
12     }
13 }
14 
15 ll cal(ll x){
16     int tot=0;ll ret=0;
17     for(int i=31;i>0;i--){
18         if(x&((ll)1<<i)){
19             ++tot;
20             if(tot>k)break;
21         }
22         if(x&(1<<(i-1)))
23             ret+=f[i-1][k-tot];
24     }
25     if(tot+x==k)++ret;
26     return ret;
27 }
28 
29 ll solve(ll x){
30     if(b==2)return cal(x);
31     memset(d,0,sizeof(d));
32     int len=0;
33     while(x>0){
34         d[len++]=x%b;
35         x/=b;
36     }
37     int id=len-1;
38     while(id>=0&&d[id]<2)id--;
39     for(int i=0;i<=id;i++)d[i]=1;
40     ll tmp=0,q=1;
41     for(int i=0;i<len;i++){
42         tmp+=d[i]*q;
43         q*=2;
44     }
45     return cal(tmp);
46 }
47 
48 int main(){
49     init();ll x,y;
50     while(cin>>x>>y>>k>>b)
51         cout<<solve(y+1)-solve(x-1)<<endl;
52 
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/jihe/p/5744133.html