题目大意:
超级幂:是至少两个数的幂;
输出1~2^64-1 的所有超级幂;
解题思路:
首先想到肯定是用素数来筛选,但是不可能用素数来筛选可行解,比如:
素数2,枚举2的幂,在进行比较,绝对超时;
那我们只能将素数用于幂的选择上也就是素数不选;
但这样仍然过不了,会越界;
这里可以使用两种优化边界处理方式:
1、我自己是定义了一个中间变量ans,幂次循环枚举的时候,判断ans是否大于INF/i,i是当前的底数;可以完美处理边界;
2、这种方式应该是一般思路,就是利用log函数,
因为i^j 要求小于2的64次方-1,但并不能算出大于2^64的数,我们可以用log优化,
log(i^j) <= log(2^64);
j <= 64*log(2)/log(i);
但是这种方式有点缺陷,就是精度不好控制,但这也是日后应该能常用到的方式;
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 1e5
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define mc(x, y) memcpy(x, y, sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ull INF = (1<<64) -1;//(ll)1e18+300;
const int maxd = 65555;
int m, n;
int pri[maxd];
int vis[maxd];
int num;
void init() {
ms(pri, 0);
ms(vis, 0);
num = 0;
for (int i = 2; i < maxd; i++) {
if(!vis[i]) {
pri[num ++] = i;
for (int j = 2*i; j <= maxd; j += i){
vis[j] = 1;
}
}
}
}
int main(){
init();
set<ull> s;
set<ull>::iterator it;
//while (cin >> n && n) {
for (ull i = 2; i <= 65536;i ++) {
ull ans = 1;
//int ans = pri[i];
//double res = (1LL<<64);
//double cnt = 64*log(2)/log(i*1.0)-1;
//cout << cnt << endl;
for (ull j = 1; j <= 64; j ++) {
ans *= i;
//
//if(((ansLL)<<(jLL)) < )
if(vis[j]) {s.insert(ans);
// continue;
}//cout <<i <<" "<< num << "asd" << endl;
//cout <<i << " "<< j <<" " << (i<<j) << endl;
// if(ans == 0)
// cout <<i <<" " <<j << " ans " << ans << " " << INF/i <<endl;
if(ans > INF/i) {
break;
}
}
}
s.insert(1);
for (it = s.begin(); it != s.end(); it++){
cout << *it << endl;
}
return 0;
}