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; }