数论 + 离散化 - The Super Powers - UVA 11752

数论 + 离散化 - The Super Powers - UVA 11752

题意:

若 一 个 数 能 够 转 化 为 两 个 不 同 正 整 数 的 幂 , 则 称 这 个 数 是 若一个数能够转化为两个不同正整数的幂,则称这个数是 The Super Power Numbers

例 如 : 64 = 8 2 = 4 3 例如:64=8^2=4^3 64=82=43

输 出 [ 1 , 2 64 − 1 ] 以 内 的 所 有 S u p e r   P o w e r   N u m b e r s 输出[1,2^{64}-1]以内的所有Super\ Power \ Numbers [1,2641]Super Power Numbers

Sample Input

Sample Output

1
16
64
81
256
512
.
.
.

分析:

假 设 正 整 数 X = P k , 若 X 为 S u p e r   P o w e r   N u m b e r s , 必 有 X = P 1 k 1 k , 假设正整数X=P^{k},若X为Super\ Power \ Numbers,必有X=P_1^{k_1k}, X=PkXSuper Power NumbersX=P1k1k

其 中 P = P 1 k 1 , 且 k 1 ≥ 2 其中P=P_1^{k_1},且k_1\ge 2 P=P1k1k12

这 意 味 着 k 是 一 个 大 于 2 的 合 数 。 这意味着k是一个大于2的合数。 k2

且 k 的 上 界 是 64 , 下 界 是 4 。 且k的上界是64,下界是4。 k644

因 此 , 我 们 暴 力 枚 举 底 数 到 ( 2 64 − 1 ) 1 4 , 指 数 到 64 , 再 判 断 即 可 。 因此,我们暴力枚举底数到(2^{64}-1)^{\frac{1}{4}},指数到64,再判断即可。 (2641)4164

将 所 有 符 合 条 件 的 数 保 存 下 来 , 排 序 再 判 重 , 最 后 输 出 。 将所有符合条件的数保存下来,排序再判重,最后输出。

注意:

边 界 位 置 需 要 格 外 注 意 , 在 枚 举 指 数 的 时 候 可 能 会 爆 u l l 。 边界位置需要格外注意,在枚举指数的时候可能会爆ull。 ull

解 决 方 案 , 当 x i > i n f 时 退 出 , 为 了 防 止 溢 出 , 可 在 前 一 次 循 环 , 当 x i > i n f / x 时 提 前 退 出 。 解决方案,当x^i>inf时退出,为了防止溢出,可在前一次循环,当x^i>inf/x时提前退出。 xi>inf退xi>inf/x退

代码:

#include 
#include 
#include 
#include 
#include 

#define ull unsigned long long

using namespace std;

const int N=100010;
const ull inf=(1<<64)-1;

ull ans[N], idx;

bool check(int x)
{
     
    for(int i=2;i<=x/i;i++)
        if(x%i==0) 
            return false;
    return true;
}

void cal(ull x)
{
     
    ull tmp=1;
    for(int i=1;i<=64;i++)
    {
     
        tmp*=x;
        if(!check(i)) ans[idx++]=tmp;
        if(tmp>inf/x) break;
    }
}

int main()
{
     
    ans[idx++]=1;
    for(int i=2;i<=65536;i++) cal(i);
    sort(ans,ans+idx);
    int n=unique(ans,ans+idx)-ans;
    for(int i=0;i<n;i++) printf("%llu\n",ans[i]);

    return 0;
}

你可能感兴趣的:(数论,数论,离散化,ACM,算法)