1 条题解
-
0
自动搬运
来自洛谷,原作者为

zgy_123
今天,是你我人生中最年轻的一天。搬运于
2025-08-24 22:45:30,当前版本为作者最后更新于2023-03-11 16:02:32,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
鸣谢
https://www.luogu.com.cn/user/20562的老师。首先,显而易见,当 时,是可以通过枚举底数的暴力来解决的,附上 分代码:
#include<bits/stdc++.h> using namespace std; #define ll long long map <ll,bool> mp; ll cnt; void solve(ll n,ll k){ for(ll i=2;i*i*i<=n;i++){//枚举底数,只看3次方就够了 ll t=i*i,m=2;//表示i^m=t while(t<=n/i){ t*=i,m++; if(m<k) continue;//次数不够 if(mp[t]) continue;//已经有了 mp[t]=1,cnt++; } } } int main(){ ll n,k; cin>>n>>k; solve(n,k); if(k==1) cout<<n; else if(k>=3) cout<<cnt+1;//加1,因为1没有被判断过 return 0; }(说句闲话,如果这样提交会获得link)
接下来处理平方的判断。
我们知道, 以内的完全平方数一共有 个,但是其中有些数字已经被标记过了。
如果一个一个去判断,显然不可行。这时候,我们可以在标记时判断是否为完全平方数。
接下来附上最短 AC 代码:
#include<bits/stdc++.h> using namespace std; #define ll long long map <ll,bool> mp; ll x,cnt; void solve(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; if(mp[t]) continue; if((ll)sqrtl(t)*sqrtl(t)==t) x++;//是完全平方数 mp[t]=1,cnt++; } } } int main(){ ll n,k; cin>>n>>k; solve(n,k); if(k==1) cout<<n; else if(k>=3) cout<<cnt+1; else cout<<(ll)sqrtl(n)+cnt-x;//不用加一,因为在sqrtl里算上了 return 0; }良心提供 组 hack 数据:
imput:576460752303423488 2 output:760085356 imput:99 100 output:1再说句闲话,数据里好像只有 的数据点。
- 2023.3.11 过审
- 2023.3.12 添加压行部分,修改语病
- 2023.3.22 添加 hack 数据
- 1
信息
- ID
- 8449
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者