UVA11752 The Super Powers 【暴力+数学】
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;
}
美团成长空间 2663人发布
