Description
Create a code to determine the amount of integers, lying in the set [ X; Y] and being a sum of exactly K different integer degrees ofB.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 2 4+2 0,
18 = 2 4+2 1,
20 = 2 4+2 2.
18 = 2 4+2 1,
20 = 2 4+2 2.
Input
The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 2 31−1). The next two lines contain integers Kand B (1 ≤ K ≤ 20; 2 ≤ B ≤ 10).
Output
Output should contain a single integer — the amount of integers, lying between X and Y, being a sum of exactly K different integer degrees of B.
Sample Input
input | output |
---|---|
15 20 2 2 |
3 |
Source
Problem Source: Rybinsk State Avia Academy
题解:
所求的数为互不相等的幂之和,亦即其B进制表示的各位数字都只能是0和1。 因此,我们只需讨论二进制的情况,其他进制都可以转化为二进制求解。
设f[i,j]代表i位二进制数中恰好有j个1的数的个数。其实这个就是组合数。
最后的问题就是如何处理非二进制。 对于询问n,我们需要求出不超过n的最大B进制表示只含0、1的数:找到n的左起第一位非0、1的数位,将它变为1,并将右面所有数位设为1。 将得到的B进制表示视为二进制进行询问即可。 如n = (10204)9进制 n = (10111)2进制
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 char ch; 8 bool ok; 9 void read(int &x){ 10 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 11 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 12 if (ok) x=-x; 13 } 14 const int maxl=33; 15 int l,r,k,b,c[maxl][maxl],len,a[maxl],ans; 16 void init(){ 17 for (int i=0;i<=32;i++) c[i][0]=1; 18 for (int i=1;i<=32;i++) for (int j=1;j<=i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j]; 19 } 20 int calc(int n){ 21 int t=n,len=0,res=0,ans=0; 22 memset(a,0,sizeof(a)); 23 while (t) a[++len]=t%b,t/=b; 24 for (int i=len;i;i--) if (a[i]!=0&&a[i]!=1){ 25 for (;i;i--) a[i]=1; 26 break; 27 } 28 for (int i=len;i;i--) if (a[i]) ans+=c[i-1][k-res],res++; 29 return ans; 30 } 31 int main(){ 32 init(); 33 read(l),read(r),read(k),read(b); 34 printf("%d ",calc(r+1)-calc(l)); 35 return 0; 36 }