题解 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;
}
上一篇:回顾sql语句中的各种连接


下一篇:程序刷题笔记-第二篇