n范围为1e18,普通暴力肯定行不通,我们可以发现,当y1=2,y2=3这种情况,是肯定符合题意的,我们对n进行质因数分解,因为刚刚所说,指数为5,所以我们只需要筛出以内的素数即可,大概是4000多,如果说,分解到某个质因数时,该质因数只出现了一次,我们就直接输出no,因为此时不符合y1,y2大于等于2的条件,当质因数分解完后,我们去判断此时的n是否为平方数或者立方数即可,因为前面的质因数分解都是符合条件的,当一个数在n中出现x次(x>1),那么该数肯定能拆分为2*a+3*b的形式。所以我们不管前面有多少组质因数,只要是符合条件的,最后的指数一定会是y1=2,y2=3的形式。举个例子,我们分解得到了x出现5次,y出现7次,z出现3次,那么x1=,y1即为3,x2=,y2为2。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef unsigned long long ull;
vector<int> prime;
int st[5000];
int cnt;
void getprime()//欧拉筛
{
int i,j;
for(i=2;i<=4500;i++){
if(!st[i]){
prime.push_back(i);
}
for(j=0;i*prime[j]<=4500;j++){
st[i*prime[j]]=1;
if(i%prime[j]==0){
break;
}
}
}
}
ll cbr(ll x)
{
return 1ll*x*x*x;
}
bool check(ll x)
{
ll a=(int)sqrt(x);
if(1ll*a*a==x){
return 1;
}
ll y=(int)cbrt(x);
if(cbr(y)==x||cbr(y+1)==x||cbr(y-1)==x){//数字太大有误差
return 1;
}
return 0;
}
void solve()
{
ll n;
cin>>n;
for(int i=0;i<prime.size();i++){
ll x=prime[i];
int cur=0;
if(n%x==0){
while(n%x==0){
n/=x;
cur++;
}
}
if(cur==1){
cout<<"no"<<endl;
return ;
}
}
if(check(n)){
cout<<"yes"<<endl;
}
else{
cout<<"no"<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
cin >> t;
getprime();
while(t--){
solve();
}
system("pause");
return 0;
}