题目链接:https://ac.nowcoder.com/acm/contest/4629/E
题目大意:
对于给定的正整数 N,求最大的正整数 A,使得存在正整数 B,满足 A 3 B A^3B A3B=N,输入包含 T 组数据,1≤T≤10,000;1≤N≤ 1 0 18 10^{18} 1018
题目思路:
第一眼, A 3 A^3 A3最大那就是所有次数超过3的肯定都得给A啊,那肯定就是直接质因数分解,然后看所有指数/3是多少就给答案乘多少直接秒杀啊,后来一看范围,默默闭上嘴巴。分解质因数sqrt的复杂度连一组都过不去,咋办?然后可以发现,可以枚举质因数,1e9之内的质因数肯定没法了,但是可以发现是三次方才到N,所以符合要求的质因数最大也就 n 1 3 n^{\frac{1}{3}} n31,也就1e6嘛,但是,可以发现尼玛1e6内的质因数多达78498,那对于T直接凉凉。那咋办呢?继续缩小! n 1 4 n^{\frac{1}{4}} n41才到31623,就当40000,内部的质数数量也就4203,4e7的复杂度是够通过1s的!那么,只到 1 4 \frac{1}{4} 41,剩下到1e6那部分可咋办?不用慌!可以发现一个牛B的事实,那就是大于 n 1 4 n^{\frac{1}{4}} n41的部分想对答案有贡献,那最多只有一个。为啥呢,假如有两个符合要求的小伙子,那么他们相乘最少都有 n 1 2 n^{\frac{1}{2}} n21,要是再来三次,就 n 3 2 n^{\frac{3}{2}} n23超过n了,所以这肯定不可能。如果只有一个小伙子的话也容易,因为它大于 n 1 4 n^{\frac{1}{4}} n41,所以4次方肯定不行了,直接超过n了,如果只有1次或者2次那对答案没贡献,也就是这个小伙子除非是一个立方数,否则就没用了。所以在1~1e6里面二分,来判断这家伙是不是一个立方数就行。是的话算上它的贡献就是答案案。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
const int MAXN =1e6+5;
const int MAXM = 4e7+5;
const int MOD = 1e9+7;
bool vis[MAXN];
int a[MAXN];
ll n;
int main()
{
int tot=0;
rep(i,2,4e4){
if(vis[i])continue;
a[++tot]=i;
for(int j=i+i;j<=4e4;j+=i)vis[j]=1;
}
int t;
scanf("%d",&t);
while(t--){
scanf("%lld",&n);
ll ans=1;
rep(i,1,tot){
if(n%a[i]==0){
int num=0;
while(n%a[i]==0){
num++;
n/=a[i];
}
num=num/3;
rep(j,1,num)ans*=a[i];
}
}
ll l=1,r=1e6;
while(l<=r){
ll mid=(l+r)>>1;
ll temp=mid*mid*mid;
if(temp==n){
ans*=mid;
break;
}
if(temp>n)r=mid-1;
else l=mid+1;
}
printf("%lld\n",ans);
}
}