给定一个正整数 k k k,把所有 k k k的方幂及所有有限个互不相等的 k k k的方幂之和构成一个递增的序列,例如,当 k = 3 k=3 k=3时,这个序列是:
1 , 3 , 4 , 9 , 10 , 12 , 13 , … 1,3,4,9,10,12,13,… 1,3,4,9,10,12,13,…
该序列实际上就是:
3
0
3^{0}
30,
3
1
3^1
31,
3
0
+
3
1
3^0+3^1
30+31,
3
2
3^2
32,
3
0
+
3
2
3^0+3^2
30+32,
3
1
+
3
2
3^1+3^2
31+32,
3
0
+
3
1
+
3
2
3^0+3^1+3^2
30+31+32,…
请你求出这个序列的第
N
N
N项的值(用
10
10
10进制数表示)。
例如,对于 k = 3 , N = 100 k=3,N=100 k=3,N=100,正确答案应该是 981 981 981。
输入格式
输入文件只有
1
1
1行,为
2
2
2个正整数,用一个空格隔开:
k
N
k N
k N。
输出格式
输出文件为计算结果,是一个正整数(在所有的测试数据中,结果均不超过
2.1
∗
1
0
9
)
2.1∗10^9)
2.1∗109)。(整数前不要有空格和其他符号)。
数据范围
3
≤
k
≤
15
,
10
≤
N
≤
1000
3≤k≤15,\\ 10≤N≤1000
3≤k≤15,10≤N≤1000
输入样例:
3 100
输出样例:
981
算法
(数学,二进制,位运算)
O
(
k
l
o
g
n
)
O(klogn)
O(klogn)
引理:
当
k
≥
2
时
,
k
m
>
k
0
+
k
1
+
…
+
k
m
−
1
当 k≥2 时,k^m>k^0+k^1+…+k^{m−1}
当k≥2时,km>k0+k1+…+km−1。
证明:对 m m m由数学归纳法可证。
假设当
m
=
m
0
m=m_0
m=m0 时是正确的,那么当
m
=
m
0
+
1
m=m_0+1
m=m0+1 时:
k
m
0
+
1
k^{m_0+1}
km0+1≥
k
m
0
k^{m_0}
km0+
k
m
0
k^{m_0}
km0>
k
0
+
k
1
+
…
+
k
m
0
−
1
+
k
m
0
k^0+k^1+…+k^{m_0−1}+k^{m_0}
k0+k1+…+km0−1+km0
接下来将序列中的每个数,唯一映射到一个二进制数:
如果第
i
i
i 个方幂存在,则二进制数的第
i
i
i 位为
1
1
1,否则为
0
0
0。
由上述引理,序列中任意两数的大小关系,和映射成二进制数后的大小关系相同。
因此我们可以先求出第
n
n
n 个二进制数,然后再反射出原数即可。
#include <bits/stdc++.h>
using namespace std;
int k, n, ans;
int ksm(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
int main() {
scanf("%d%d", &k, &n);
int i = 0;
while (n) {
if (n & 1) {
ans += ksm(k, i);
}
i++;
n >>= 1;
}
printf("%d\n", ans);
return 0;
}