ural 1057 Amount of degrees 题解

 

题目大意:统计区间[x,y]中在b进制下含k个1的数字个数。

数位dp。

具体见2009刘聪论文《浅谈数位类统计问题》...

 1 #include<cstdio>
 2 const int MAXN=32;
 3 int f[MAXN][MAXN];
 4 void init()
 5 {
 6     f[0][0]=1;
 7     for(int i=1;i<MAXN;++i)
 8     {
 9         f[i][0]=f[i-1][0];
10         for(int j=1;j<=i;++j)
11             f[i][j]=f[i-1][j-1]+f[i-1][j];
12     }
13 }
14 int tran(int x,int b)
15 {
16     int s[101];
17     int p=0;
18     while(x)
19     {
20         s[p++]=x%b;
21         x/=b;
22     }
23     for(int i=p-1;i>=0;--i) if(s[i]>1)
24     {
25         for(int j=i;j>=0;--j) s[j]=1;
26         break;
27     }
28     int ans=0;
29     for(int i=0;i<p;++i) if(s[i]) ans|=1<<i;
30     return ans;
31 }
32 int cal(int x,int k)
33 {
34     int tot=0,ans=0;
35     for(int i=MAXN-1;i>=0;--i)
36     {
37         if(x&(1<<i))
38         {
39             ++tot;
40             if(tot>k) break;
41             x^=1<<i;
42         }
43         if((1<<(i-1))<=x)
44             ans+=f[i-1][k-tot];
45     }
46     if(tot+x==k) ++ans;
47     return ans;
48 }
49 int k,b,x,y;
50 int main()
51 {
52     scanf("%d%d%d%d",&x,&y,&k,&b);
53     init();
54     x=tran(x,b);y=tran(y,b);
55     printf("%d\n",cal(y,k)-cal(x-1,k));
56     return 0;
57 }
View Code

 

转载于:https://www.cnblogs.com/lowsfish/p/4332819.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值