题目传送门
# [春季测试 2023] 幂次
题目描述
小 Ω 在小学数学课上学到了“幂次”的概念:$\forall a, b \in \N^+$,定义 $a^b$ 为 $b$ 个 $a$ 相乘。
她很好奇有多少正整数可以被表示为上述 $a^b$ 的形式?由于所有正整数 $m \in N^+$ 总是可以被表示为 $m^1$ 的形式,因此她要求上述的表示中,必须有 $b \geq k$,其中 $k$ 是她事先选取好的一个正整数。
因此她想知道在 $1$ 到 $n$ 中,有多少正整数 $x$ 可以被表示为 $x = a^b$ 的形式,其中 $a, b$ 都是正整数,且 $b \geq k$?
输入格式
第一行包含两个正整数 $n, k$,意义如上所述。
输出格式
输出一行包含一个非负整数表示对应的答案。
样例 #1
样例输入 #1
99 1
样例输出 #1
99
样例 #2
样例输入 #2
99 3
样例输出 #2
7
样例 #3
样例输入 #3
99 2
样例输出 #3
12
提示
【样例 2 解释】
以下是全部 $7$ 组符合题意的正整数及对应的一种合法的表示方法。
$1 = 1^3, 8 = 2^3, 16 = 2^4, 27 = 3^3, 32 = 2^5, 64 = 4^3, 81 = 3^4$
注意某些正整数可能有多种合法的表示方法,例如 $64$ 还可以表示为 $64 = 2^6$。
但根据题意,同一个数的不同的合法表示方法只会被计入一次。
【样例 3 解释】
以下是全部 $12$ 组符合题意的正整数及对应的一种合法的表示方法。
$1 = 1^2, 4 = 2^2, 8 = 2^3, 9 = 3^2, 16 = 4^2, 25 = 5^2, 27 = 3^3, 32 = 2^5, 36 = 6^2, 49 = 7^2, 64 = 8^2, 81 = 9^2$
【样例 4】
见选手目录下的 power/power4.in 与 power/power4.ans。
【样例 5】
见选手目录下的 power/power5.in 与 power/power5.ans。
【样例 6】
见选手目录下的 power/power6.in 与 power/power6.ans。
【数据范围】
对于所有数据,保证 $1 \leq n \leq 10^{18}$,$1 \leq k \leq 100$。
测试点编号 | $n \le$ | $k$ |
---|---|---|
1 | $10^2$ | $=1$ |
2 | $10^2$ | $\ge 2$ |
3 | $10^4$ | $\ge 3$ |
4 | $10^4$ | $\ge 2$ |
5 | $10^6$ | $\ge 3$ |
6 | $10^6$ | $\ge 2$ |
7 | $10^8$ | $\ge 3$ |
8 | $10^8$ | $\ge 2$ |
9 | $10^{10}$ | $\ge 3$ |
10 | $10^{10}$ | $\ge 2$ |
11 | $10^{12}$ | $\ge 3$ |
12 | $10^{12}$ | $\ge 2$ |
13 | $10^{14}$ | $\ge 3$ |
14 | $10^{14}$ | $\ge 2$ |
15 | $10^{16}$ | $\ge 3$ |
16 | $10^{16}$ | $\ge 2$ |
17 | $10^{18}$ | $\ge 3$ |
18 | $10^{18}$ | $\ge 2$ |
19 | $10^{18}$ | $\ge 2$ |
20 | $10^{18}$ | $\ge 2$ |
这道题很自然想到一个枚举做法,这里就不赘述了
这里详尽的讲解一下一个来源于洛谷题解的代码
出处
那么这道题的思想就是数量的统计与筛选,K一共分为三类
K=1,K=2,K=3。
最简单的是K=1。
直接输出一个n就完了
重要的是后两个
K=3
K=3是第二简单的
只需要考虑一个中不中的问题
所以我们只要来个标记就OK来
这里bool数组显然不适用
所以用一个map来
map<ll,bool> mp;
ll x,cnt;
void fir(ll n,ll k){
for(ll i=2;i*i*i<=n;i++){
ll t=i*i,m=2;
while(t<=n/i){
t*=i;
m++;
if(m<k) continue;
else if(mp[t]) continue;
mp[t]=1;
cnt++;
}
}
}
就这样就OK了
K=2的时候
这个时候就不能拘泥于单单都统计了,要涉及到一个完全平方数的问题
据容斥原理
可得下面代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,bool> mp;
ll x,cnt;
void fir(ll n,ll k){
for(ll i=2;i*i*i<=n;i++){
ll t=i*i,m=2;
while(t<=n/i){
t*=i;
m++;
if(m<k) continue;
else if(mp[t]) continue;
if((ll)sqrtl(t)*sqrtl(t)==t) x++;
mp[t]=1;
cnt++;
}
}
}
int main(){
ll n,k;
cin>>n>>k;
fir(n,k);
if(k==1) cout<<n;
else if(k>=3) cout<<cnt+1;
else cout<<(ll)sqrtl(n)+cnt-x;
return 0;
}