1057. Amount of Degrees

Time limit: 1.0 second
Memory limit: 64 MB
Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK 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 = 24+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 ≤ 231−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.

Sample

input output
15 20
2
2
3
Problem Source: Rybinsk State Avia Academy
思路:转成B进制,只要是B进制打头的是01皆可以。DP之

#include<iostream>
#include<cstring>
#include<cstdio>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define clr(f,z) memset(f,z,sizeof(f))
using namespace std;
const int mm=65;
int f[mm][mm];
int bit[mm];
int DP(int n,int num,int b)
{
    int pos=0;
    while(n)
    {
        bit[++pos]=n%b;n/=b;
    }
    int ret=0,one=0;
    for(int i=pos;i>=1;--i)
    {
        if(bit[i]>1)
        {ret+=f[i][num-one];break;//已经大于了
        }
        else if(bit[i])
        {
            ret+=f[i-1][num-one];++one;//相等则下一层可选,多一个1
        }
        if(i==1&&one==num)++ret;//相等的情况
    }
    return ret;
}
int main()
{
    FOR(i,0,mm-1)f[i][0]=1;
    FOR(i,1,mm-1)FOR(j,1,mm-1)
    f[i][j]=f[i-1][j-1]+f[i-1][j];//0 or 1
    int X,Y,K,B;
    while(~scanf("%d%d%d%d",&X,&Y,&K,&B))
    {
        printf("%d\n",DP(Y,K,B)-DP(X-1,K,B));
    }
    return 0;
}



The article write by nealgavin