https://ac.nowcoder.com/acm/contest/3007/E
先用N^(1/4)以内的质数,若N里有x个质数pi相乘,则答案乘上pi^(x/3)
然后剩下的N至多是3个质数的乘积
所以若还能凑出一个质数,那剩下的N一定是一个立方数,在N^(1/4)到N^(1/6)里面二分即可
#include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 1000001 typedef long long LL; bool vis[N]; int m,m2,p[N]; LL pp[N]; void pre() { for(int i=2;i<N;++i) { if(!vis[i]) { p[++m]=i; if(i>31700) pp[++m2]=i; } for(int j=1;j<=m && p[j]*i<N;++j) { vis[p[j]*i]=true; if(!(i%p[j])) break; } } } LL Pow(LL a,int b) { LL s=1; for(;b;b>>=1,a=a*a) if(b&1) s=s*a; return s; } int main() { pre(); for(int i=1;i<=m2;++i) pp[i]=pp[i]*pp[i]*pp[i]; int T,sum,m1=m-m2,t; LL n,ans; scanf("%d",&T); while(T--) { scanf("%lld",&n); ans=1; for(int i=1;i<=m1;++i) if(!(n%p[i])) { sum=0; while(!(n%p[i])) { sum++; n/=p[i]; } if(sum>=3) ans*=Pow(p[i],sum/3); } t=lower_bound(pp+1,pp+m2+1,n)-pp; if(pp[t]==n) ans*=p[m1+t]; printf("%lld ",ans); } return 0; }