The Super Powers

题目

若x可以表示成两种及以上的幂形式,比如,被成为超级power数,现在让输出 范围内的所有超级power数

分析

有限其实就是unsinged long long 的最大值,大概1e19,我们是无法通过直接暴力枚举的,那么就考虑下是否可以优化,题目说到至少要有2个幂形式,所以中的y至少大于等于4,小于63(x = 1除外)。所以我们可以枚举x,,然后的y我们发现,只要y是一个合数,那么至少可以把表示成2种形式。因为x和y的范围都知道了,所以就可以开始枚举了。

关于log函数

当我们要求的y最大是多少,让其不超过unsinged long long的值,数学上我们可以直接算 ,但是这里中参数太大了,非常影响精度,我们可以写成,64*log(2)/log(x)肯定会比正确值大一点,所以我们可以向上取整再减一,就取到整数部分了。(好吧,这里我强行解释了,我也不知道为啥floor行不通)

AC 代码

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <set>
#include <cmath>
using namespace std;
typedef unsigned long long ll;
const ll maxn = (1LL<<16);
set<ll> st;
bool vis[100];

ll ksm(ll a,ll b){
    ll res = 1;
    while(b){
        if(b&1) res = res*a;
        a = a*a;
        b>>=1;
    }
    return res;
}
void init(){
    for(ll i =2;i<=64;i++){
        if(!vis[i]){
            for(ll j = i*i;j<=64;j+=i){
                vis[j] = true;
            }
        }
    }
    st.insert(1);
    for(ll i = 2;i<maxn;i++){
        ll len = ceil(64*log(2)/log(i))-1; //最大次幂
        for(ll j = 4;j<=len;j++){
            if(!vis[j]) continue;//如果不是合数,就跳过
            ll t = ksm(i,j);
            st.insert(t);
        }
    }
}
int main(){
    init();
    for(auto v:st){
        printf("%llu\n",v);
    }
    return 0;
}