题解 CF1594B
Description
如果一个正整数可以被表示为 \(n\) 的若干个不同的非负整数次幂的和,则称这个正整数是特别的。求出第 kk 小的特别的数
Solution
我们拿 \(n=2\) 举例,
序列为 \(2^0,2^1,2^1+2^0,2^2,2^2+2^0,2^2+2^1,2^2+2^1+2^0,2^3\dots\)
我们设二进制位的每一位 \(i\) 表示 \(n^i\) 这一位选不选。
将上述序列表示一下,
\(1,10,11,100,101,110,111,1000,\dots\)
将这个二进制序列转化为十进制,
\(1,2,3,4,5,6,7,8,\dots\)
我们发现,其实第 \(k\) 位其实就是其对应的二进制的对应的位选与不选。
比如 \(k=5\)
也就是 \(n^2+n^0\)。
Code
/* * @Author: smyslenny * @Date: 2021.10.10 * @Title: CF1594B * @Main idea:找规律 */ #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <iomanip> #include <cstring> #include <cstdlib> #include <queue> #include <vector> #define int long long #define INF 0x3f3f3f3f #define orz cout<<"LKP AK IOI\n" #define MAX(a,b) (a)>(b)?(a):(b) #define MIN(a,b) (a)>(b)?(a):(b) using namespace std; const int mod=1e9+7; const int M=1e3+5; int T,n,k; int read() { int x=0,y=1; char c=getchar(); while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();} while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();} return y?x:-x; } signed main() { T=read(); while(T--) { n=read(),k=read(); int sum=1,Ans=0; for(int i=0;i<31;i++) { if(k&(1<<i)) Ans=(Ans+sum)%mod; sum=(sum*n)%mod; } printf("%lld\n",Ans); } return 0; }