UVA11752-The Super Powers(素数表+log)

题目链接


题意:如果有一个数至少是两个不同的正整数的幂,那么称它为超级幂。按照升序输出1~2^64-1之间的所有超级幂。

思路:n = a ^ i = b ^ j,那么就证明指数要为合数,所以只要找出64以内的所以合数,然后枚举在1 << 16之内的数为底数的值,这里要注意溢出问题,要求出每个底数a的所能得到的最大幂,所以max = (log(2 ^ 64 -1) / log(a));

代码;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>

using namespace std;

typedef unsigned long long ull;

const int MAXN = 100;

int vis[MAXN];

set<ull> arr;
set<ull>::iterator it;

void init() {
    memset(vis, 0, sizeof(vis));    
    for (int i = 2; i < MAXN; i++) {
        if (!vis[i])
        for (int j = i * 2; j < MAXN; j += i)
            vis[j] = 1;;
    }
}

ull pow(int n, int k) {
    if (k == 0) return 1;
    if (k == 1) return n;
    ull a = pow(n, k / 2);
    ull ans = a * a;
    if (k % 2)
        ans = ans * n;
    return ans;
}

int main() {
    init();
    arr.clear();
    arr.insert(1);

    double lmax = log(pow(2.0, 64) - 1);
    for (int i = 2; i < (1 << 16); i++) {
        int l = ceil(lmax / log(i)); 
        for (int j = 4; j < l; j++) {
            if (vis[j]) {
                ull num = pow(i, j); 
                if (!arr.count(num)) 
                    arr.insert(num);
            } 
        }  
    }

    for (it = arr.begin(); it != arr.end(); it++)
        cout << *it << endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值