描述
求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和。
例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:
17 = 24+20,
18 = 24+21,
20 = 24+22。
输入
第一行包含两个整数X和Y。接下来两行包含整数K和B。
输出
只包含一个整数,表示满足条件的数的个数。
样例输入
15 20
2
2
样例输出
3
提示
数据规模:1 ≤ X ≤ Y ≤ 2^31−1,1 ≤ K ≤ 20, 2 ≤ B ≤ 10
数位dp经典题。
感觉快被自己蠢哭了。
这么简单的题居然调了那么久,结果是少打了一个 ~ 2333。。。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll l,r,k,b,mul[35],len,num[35],f[35][25];
inline ll dfs(ll pos,ll cnt,ll lim){
if(pos==len+1)return cnt==k;
if((!lim)&&~f[pos][cnt])return f[pos][cnt];
ll tmp=0,up=lim?num[pos]:1;
for(ll i=0;i<=up;++i)if(cnt+i<=k)tmp+=dfs(pos+1,cnt+i,(lim&&(i==up)));
if(!lim)f[pos][cnt]=tmp;
return tmp;
}
inline ll solve(ll x){
if(!x)return 0;
for(len=0;mul[len]<=x;++len);
--len,memset(f,-1,sizeof(f));
for(ll i=len;~i;--i){
if(x>=mul[i])x-=mul[i],num[i]=1;
else num[i]=0;
}
reverse(num,num+len+1);
return dfs(0,0,1);
}
int main(){
cin>>l>>r>>k>>b,mul[0]=1;
for(ll i=1;mul[i-1]<=r;++i)mul[i]=mul[i-1]*b;
cout<<solve(r)-solve(l-1);
return 0;
}