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 of B.

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+20,
18 = 24+21,
20 = 24+22.


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 K and 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.

Example

input

output

15 2022

3


题目大概:

给出x,y,k,b,找出x和y之间含有k个项组成,每个项都是b的某次方。

思路:

如果是二次方,可以把它想成一颗完全二叉树,每个节点的左右孩子分别为0或1,每个1代表一个项,找出含有k个1的数字的数量。

这棵树用dp来建立。

其他的b也可以用这个来实现。

这个原理​​刘聪的浅谈数位​​讲的很详细。当一眼看到这个题,我也是一脸懵。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int f[33][33];
int a[33];
int b;
void init()
{ memset(f,0,sizeof(f));
f[0][0]=1;
for(int i=1;i<=31;i++)
{
f[i][0]=f[i-1][0];
for(int j=1;j<=i;j++)
{
f[i][j]=f[i-1][j]+f[i-1][j-1];
}
}

}

int sove(int x,int k)
{
int pos=1;
while(x)
{
a[pos++]=x%b;
x/=b;
}
int ans=0;
for(int i=pos-1;i>=1;i--)
{
if(a[i]>1)
{
ans+=f[i-1][k]+f[i-1][k-1];
break;
}
else if(a[i]==1)
{
ans+=f[i-1][k];
k--;
}
if(k<0)break;

}
return ans;
}
int main()
{
int n,m,k;
init();
while(~scanf("%d%d%d%d",&n,&m,&k,&b))
{
printf("%d\n",sove(m+1,k)-sove(n,k));
}
return 0;
}