题目链接:https://vjudge.net/contest/196700#problem/Y
题意:输出所有满足是任意两个数两个或以上的次方的数字num(1<=num<=2^64-1)。
分析:容易发现,这个数各种形式的最大幂指数一定是合数,因为只有合数才可以拆分为两个数之积(除了1和本身之外),而且小于64,可以预先把所有的小于64的合数存起来,(一开始没想明白,只想到了偶数),然后依次枚举筛选满足条件的情况(最小为(2^64-1)^(1/4),另外要注意去除重复的结果。可以使用c++的set容器。注意不能使用double类型,只能使用unsigned long long int(最大为2^64-1)。虽然double表示的数据范围很大,但是是用科学计数法表示的,有效数字最多为15位。而且不能使用pow函数因为返回值为double,会有精度丢失。要用到快速幂。
代码:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
#define LL unsigned long long
set<LL> s;
const int maxn = 2*1e5;
int index[]={4,6,8,9,10,12,14,15,16,18,20,21,22,24,25,26,27,28,30,32,33,34,35,36,38,39,40,42,44,45,46,48,49,50,51,52,54,55,56,57,58,60,62,63};
LL quickmul(LL a,LL b){
LL ans = 1;
while(b){
if(b&1) ans*=a;
a=a*a,b>>=1;
}
return ans;
}
void init(){
int cnt = 0;
s.insert(1);
for(int i=2;i<maxn;i++)
for(int j=0;index[j]<64*log(2)/log(i)&&j<44;j++)
s.insert(quickmul((LL)i,(LL)index[j]));
for(set<LL>::iterator it=s.begin();it!=s.end();it++){
cout<<*it<<endl;
cnt++;
}
}
int main(){
init();
}