Luogu P9118

题面

首先 b=1 显然直接输出 n

剩下的考虑枚举指数,用 set 去重。

枚举指数 i2i>n,这样可以做到 O(n1k+n1k+1+n1k+2) 的复杂度,虽然我不会算,但是肉眼观察当 k=2 时只比根号稍微高一点。

容易发现 k=3 时,即使 n=1018 也只有大约 106 的计算量,可以考虑先把指数 3 的数先算出来,再处理指数为 2 的。

显然如果不考虑重复的话能表示为 a2,aN 的数有 n 个,从已经算出来的数中把平方数删掉即可。

这题有几个坑点,一个是如果要用快速幂要开 int128,还有一个是开根要用 sqrtl,否则会炸精度 WA。

// rp++
#include<bits/stdc++.h>
#define rep(i, s, t) for(int i = s; i <= t; ++i)
#define per(i, s, t) for(int i = s; i >= t; --i)
#define int ll
#define endl '\n'
#define F first
#define S second
typedef long long ll;
typedef __uint128_t u128;
constexpr int N = 1e5 + 5;
using namespace std;
int n, k;
u128 pw(u128 a, int b) {
    u128 res = 1;
    for(; b; b >>= 1) {
        if(b & 1) res *= a;
        a *= a;
    }
    return res;
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> k;
    if(k == 1) {
        cout << n << endl;
        return 0;
    }
    set<uint64_t> st;
    for(int i = max(k, 3ll); 1; ++i) {
        u128 tmp; int j = 1;
        if(i == 2) for(; (tmp = (u128)j * j) <= n; ++j) st.emplace(tmp);
        else for(; (tmp = pw(j, i)) <= n; ++j) st.emplace(tmp);
        if(j == 2) break;
    }
    if(k == 2) {
        int res = sqrtl(n);
        for(auto i : st) {
            int r = sqrtl(i);
            if(r * r == i) --res;
        }
        cout << st.size() + res << endl;
    }
    else cout << st.size() << endl;
    return 0;
}
posted @   untitled0  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示