【Ural 1057】Amount of Degrees

传送门


Problem

求给定区间 [    l , r    ] [\;l,r\;] [l,r] 中满足下列条件的整数个数:这个数恰好等于 k k k 个互不相等的 b b b 的整数次幂之和。

例如,设 l = 15 l=15 l=15 r = 20 r=20 r=20 k = 2 k=2 k=2 b = 2 b=2 b=2,则有且仅有下列三个数满足题意: 17 = 2 4 + 2 0 17 = 2^4+2^0 17=24+20 18 = 2 4 + 2 1 18 = 2^4+2^1 18=24+21 20 = 2 4 + 2 2 20 = 2^4+2^2 20=24+22

1 ≤ l ≤ r ≤ 2 31 − 1 1 ≤ l ≤ r ≤ 2^{31}-1 1lr2311 1 ≤ k ≤ 20 1 ≤ k ≤ 20 1k20 2 ≤ b ≤ 10 2 ≤ b ≤ 10 2b10


Solution

我们先考虑一下符合条件的数有什么特点。

比较显然的是,当这个数在 b b b 进制下 1 1 1 k k k 个,且其他位都是 0 0 0,那它就符合条件。

为什么不能有 2 2 2 或以上的数字出现呢?因为如果有 2 2 2,就不能满足是互不相等 b b b 的整数次幂之和。

所以我们用数位DP,类似于 10 10 10 进制,把这个数转换成 b b b 进制后统计 1 1 1 的个数就行了。

比较简单的一道题。


Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int l,r,k,b,a[50],f[50][50][2];
int dp(int p,int num,bool limit)
{
	if(!p)  return num==k;
	if(~f[p][num][limit])  return f[p][num][limit];
	int i,up=limit?a[p]:(b-1),ans=0;
	for(i=0;i<=up&&i<=1;++i)
		ans+=dp(p-1,num+(i==1),limit&&a[p]==i);
	return f[p][num][limit]=ans;
}
int solve(int x)
{
	int p=0;
	while(x)  a[++p]=x%b,x/=b;
	memset(f,-1,sizeof(f));
	return dp(p,0,true);
}
int main()
{
	scanf("%d%d%d%d",&l,&r,&k,&b);
	printf("%d",solve(r)-solve(l-1));
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值