样例输入:
7
2
6
12
4
8
24
72
样例输出:
no
no
no
yes
yes
no
yes
分析:由质因子分解定理我们可以知道,任意一个数x都可以唯一地分解为:
x=p1^a1 * p2^a2 * …… * pn^an
那么问我们一个数x能否表示为x1^y1 * x2^y2就等价于问我们是否存在一个数对(k1,k2)(k1,k2>=2或者等于0)使得对于任意的ai都可以表示为k1*u+k2*v=ai,有一个显然的条件是当ai=1时那么显然是不存在的。那么我们就开始讨论ai>1时是否一定存在满足题意的数对呢?答案是yes,我们如果令k1=2,k2=3,那么就是要讨论是否对于所有的ai>=2均满足2u+3v=ai有非负整数解,这个是显然的,根据翡蜀定理可以知道2*u+3*v=gcd(2,3)有解,那么gcd(2,3)|ai,所以显然是有非负整数解的。而且我们还可以直接表示出来:
对于ai%3=0,令u=0,v=ai/3
对于ai%3=1,令u=2,v=(ai-4)/3
对于ai%3=2,令u=1,v=(ai-2)/3
那么问题到这基本上就算是解决了,我们只需要判断一下ai是否大于等于2即可。
如果质因子大于4000,那么4000^2 * 4000^3>1e18,所以对于质因子大于4000的情况我们只需要判断一下该数是不是平方或者立方即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=4e3+10;
int prime[N],tt;
bool vis[N];
void init()
{
for(int i=2;i<N;i++)
{
if(!vis[i]) prime[++tt]=i;
for(int j=1;j<=tt&&i*prime[j]<N;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
}
bool check(long long x)//判断x是否为平方数或者立方数
{
long long l=1,r=1e9;
while(l<r)
{
long long mid=l+r>>1;
if(mid*mid>=x) r=mid;
else l=mid+1;
}
if(l*l==x) return true;
l=1,r=1e6;
while(l<r)
{
long long mid=l+r>>1;
if(mid*mid*mid>=x) r=mid;
else l=mid+1;
}
if(l*l*l==x) return true;
return false;
}
int main()
{
init();
int T;
cin>>T;
while(T--)
{
bool flag=true;
long long x;
scanf("%lld",&x);
for(int i=1;i<=tt;i++)
{
int cnt=0;
while(x%prime[i]==0)
{
x/=prime[i];
cnt++;
}
if(cnt==1)
{
flag=false;
break;
}
}
if(x!=1&&!check(x)) flag=false;
if(flag) puts("yes");
else puts("no");
}
return 0;
}