Descripe:

We all know the Super Powers of this world and how they manage to get advantages in political warfare or even in other sectors. But this is not a political platform and so we will talk about a different kind of super powers — “The Super Power Numbers”. A positive number is said to be super power when it is the power of at least two different positive integers. For example 64 is a super power as 64 = 8^2 and 64 = 4^3 . You have to write a program that lists all super powers within 1 and 2^64 − 1 (inclusive).

Input

This program has no input. Output Print all the Super Power Numbers within 1 and 2^64 − 1. Each line contains a single super power number and the numbers are printed in ascending order. Note: Remember that there are no input for this problem. The sample output is only a partial solution. Sample Input Sample

Output

1

16

64

81

256

512

.

.

.

题目大意:

没有输入,找出所有的超级数,超级数即可以拆分成至少两个数的幂形式。

解题思路:

一个数同时是至少两个数的幂,而a^(m * n) = (a^ m)^n = (a^ n)^m,所以当指数为合数的时候,该幂一定可以表示为两个及以上个数的幂,所以枚举所有小于2 ^ 64 - 1的合数次幂就可以了。
但是注意,不同底数的不同次幂有可能相同,所以我们用set去重,同时还能排序。
在枚举的过程中,2 ^ 64 - 1刚好是unsigned long long 的最大值,为了防止溢出,要先把每个底数的最大次幂算出来,当这个最大次幂小于最小的合数,也就是4时,枚举的底数就到了上限,可以终止了。
1是一个特殊的答案,别忘了加进去

AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#define qcin ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e5 + 5;
const double eps = 1e-6;
const long long MOD = 1000000007;

bool number[70];
ull prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61};

int main()
{
    ull lim = ~0LL >> 1;
    set<ull> st;
    memset(number, false, sizeof(number));
    for(int i = 0; i < 18; i++)
        number[prime[i]] = true;
    for(int i = 2; ; i++)
    {
        ull x = lim, p = -1;
        while(x) x /= i, p++;
        if(p < 4) break;
        ull b = i;
        for(ull j = 2; j <= p; j++)
        {
            b *= i;
            if(!number[j]) st.insert(b);
        }
    }
    st.insert(1);
    set<ull> :: iterator it;
    for(it = st.begin(); it != st.end(); it++)
        cout << *it << endl;
    return 0;
}