求给定区间 [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。
输出格式
只包含一个整数,表示满足条件的数的个数。
数据范围
1≤X≤Y≤231−1
,
1≤K≤20
,
2≤B≤10
输入样例:
15 20
2
2
输出样例:
3
注意此题在dfs的过程中,更新lim,不能和普通的十进制类似,对于普通的十进制,我们写成:
limit && i == a[pos]
limit && i == up
但对于此题,我们是枚举的每一位是否为 0 / 1 0/1 0/1,所以lim的限制只能使用第一种形式。lim是对于我们枚举原数位进行限制,但此处对于上界的确定:
int up=lim ? min(a[pos],1) : 1 ;
所以只能使用第一种形式
#include <bits/stdc++.h>using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 1e9 + 7;
const int maxv = 4e6 + 5;ll dp[200][200];
int a[200];int l,r,k,b;ll dfs(int pos,int lim,int cnt)
{if(!pos) return cnt==k;if(!lim&&dp[pos][cnt]!=-1) return dp[pos][cnt];ll res=0;int up=lim ? min(a[pos],1) : 1 ;for(int i=0;i<=up;i++){if(cnt+i>k) continue;res+=dfs(pos-1,lim&&i==a[pos],cnt+i);}if(!lim) dp[pos][cnt]=res;return res;
}ll get(ll x)
{int len = 0;while (x){a[++len] = x % b;x /= b;}return dfs(len,1,0);
}void solve()
{cin>>l>>r>>k>>b;ll ans=get(r)-get(l-1);cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;t = 1;// cin >> t;memset(dp, -1, sizeof dp);while (t--){solve();}system("pause");return 0;
}