Caddi Programming Contest 2021(AtCoder Beginner Contest 193)-C - Unexpressed-题解


题目大意

给你一个数n,你可以找一些大于1的整数a和b,如果 c = a b < n c=a^{b}<n c=ab<n,那么 c c c就是一个“可展开数”。
问1~n的“可展开数”有多少。


解题思路

2 34 = 17 , 179 , 869 , 184 > 10 , 000 , 000 , 000 2^{34}=17,179,869,184>10,000,000,000 234=17,179,869,184>10,000,000,000,也就是说1e10范围内以2为底的符合条件的数不到35个。当底数增加的10时,1e10范围内以10为底的符合条件的数剩下不到10个。总之,可展开数比不可展开数少。
(样例2中100000范围内有99634个不可展开数也能看出可展开数很少)。

我们只需要计算出可展开数的个数,就可计算出答案。

在计算可展开数的个数时,需要注意到,b>2。
n \sqrt{n} n 的平方已经等于n了。顾当底数大于 n \sqrt{n} n 时,底数就不再需要增加了。即使为1e10的数,底数的枚举范围也只是2~1e5,在时间允许范围内。


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
map<ll, bool> mp; //防止重复计算
int main()
{
    ll n, s = 0;
    cin >> n;
    ll k = sqrt(n);
    for (ll a = 2; a <= k; a++) //底数从2枚举到√n
    {
        ll b = 2; //指数从2开始枚举
        while (1)
        {
            ll c = pow(a, b);
            if (c > n) //当a^b大于n时,结束循环
                break;
            if (!mp[c]) //如果还没有出现过
            {
                mp[c] = 1; //记录下这个可展开数
                s++;
            }
            b++;
        }
    }
    printf("%lld\n", n - s);
    return 0;
}
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tisfy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值