LOJ10163 Amount of Degrees

题目描述

求给定区间 [X,Y] 中满足下列条件的整数个数:这个数恰好等于 KK 个互不相等的 BB 的整数次幂之和。例如,设 X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意

输入格式

第一行包含两个整数 X 和 Y,接下来两行包含整数 K 和 B。

输出格式

只包含一个整数,表示满足条件的数的个数。

样例

样例输入

15 20
2
2

样例输出

3

数据范围与提示

对于全部数据,1XY2^311,1K20,2B10。

______________________________________________________________________________________________

数位动归

一类区间统计问题,区间较大,无法用暴力求解或组合数学求解。

常见为求区间内满足某类条件的X进制数的个数。条件往往与数位有关。

此题:

首先,区间具有相减的性质。count[i...j]=count[ 0...j ] - count[ 0...i-1 ]。

这样问题就变成了0到i的x进制数有多少个满足条件。

因为是互不相等的k进制数,所以,转成k进制后,每个位上要么是0要么是1。

这样f[i][j]表示长度I的2进制数,有j个1的种类

f[i][j]=f[i-1][j]+f[i-1][j-1]

______________________________________________________________________________________________

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int x,y,k,b;
 4 int wei[32];
 5 int f[32][32];
 6 void prech(int &x,int b)
 7 {
 8     int js=0;
 9     while(x>0)
10     {
11         wei[++js]=x%b;
12         x/=b;
13     }
14     while(js>0)
15     {
16         if(wei[js]==1)x^=1<<(js-1);
17         else if(wei[js]>1)
18         {
19             for(int i=js;i>0;--i)x^=1<<(i-1);
20             break;
21         }
22         --js;
23     }    
24 }
25 void dp()
26 {
27     f[0][0]=1;
28     for(int i=1;i<=31;++i)
29     {
30         f[i][0]=f[i-1][0];
31         for(int j=1;j<=i;++j)f[i][j]=f[i-1][j]+f[i-1][j-1];
32     }
33 }
34 int work(int x,int k)
35 {
36     int js=0,ans=0;
37     for(int i=31;i>0;--i)
38     {
39         if(x&(1<<i))
40         {
41             ++js;
42             if(js>k)break;
43             x=x^(1<<i);
44         }
45         if((1<<(i-1))&x)ans+=f[i-1][k-js];
46     }
47     if(js+x==k)ans++;
48     return ans;
49 }
50 int main()
51 {
52     scanf("%d%d%d%d",&x,&y,&k,&b);
53     x--;
54     prech(x,b);prech(y,b);
55     dp();
56     cout<<work(y,k)-work(x,k);
57     return 0;
58 }
View Code

 

posted on 2018-12-27 15:30  gryzy  阅读(179)  评论(0编辑  收藏  举报

导航