题目链接
想要找到的特殊数字 - 洛谷
https://www.luogu.com.cn/problem/T284625?contestId=89623
解析
一共有 t 个测试案例,对于每一组测试案例,都有一个 n 和 k。我们需要输出对于 n 来说的从小到大排序后第 k 大的特殊数。
如果一个正数可以被写成 n 的不同非负幂的总和,我们就称它为特殊数。
例如:当 n = 4 时,17 可以被称为特殊数。因为
+
= 1 + 16 =17 ,17 由 n 的两个非负幂的和组成。
我们举例 n = 4;
k 的值 | 第k个特殊数 | k 的二进制表示 |
---|---|---|
1 | 1 = | 0001 |
2 | 4 = | 0010 |
3 | 5 = | 0011 |
4 | 16 = | 0100 |
5 | 17 = | 0101 |
... | ... | ... |
通过上述枚举之后就可以发现:每当 k 的二进制表示第 i 位为 1 的时候( 从右往左看 ),答案都会加上 。
也就是说,对于每一个案例,我们只需要从右往左判断 k 的二进制表示中的每一位是否为 1 即可。 当第 i 位为 1 的时候,答案只需要加上 。
代码(c++)
#include<iostream>
#include<algorithm>
using namespace std;
const int MOD=1e9+7;
int n,k;
long long ans;
int main()
{
int t; cin>>t;
while(t--)
{
long long cnt=1; ans=0;
cin>>n>>k;
for(int i=0;i<32;i++)
{
if(k>>i&1) //判断k的第i+1位是否为1
{
ans+=cnt; ans%=MOD;
}
cnt*=n; cnt%=MOD; //cnt刚好为n的i次方
}
cout<<ans<<endl;
}
return 0;
}