ural1057Amount of Degrees

时间:2023-03-09 06:04:33
ural1057Amount of Degrees

Description

Create a code to determine the amount of integers, lying in the set [ XY] 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.

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:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
const int maxl=;
int l,r,k,b,c[maxl][maxl],len,a[maxl],ans;
void init(){
for (int i=;i<=;i++) c[i][]=;
for (int i=;i<=;i++) for (int j=;j<=i;j++) c[i][j]=c[i-][j-]+c[i-][j];
}
int calc(int n){
int t=n,len=,res=,ans=;
memset(a,,sizeof(a));
while (t) a[++len]=t%b,t/=b;
for (int i=len;i;i--) if (a[i]!=&&a[i]!=){
for (;i;i--) a[i]=;
break;
}
for (int i=len;i;i--) if (a[i]) ans+=c[i-][k-res],res++;
return ans;
}
int main(){
init();
read(l),read(r),read(k),read(b);
printf("%d\n",calc(r+)-calc(l));
return ;
}