[CodeForces230B]T-primes

思路

观察发现,如果一个数\(x\)\(3\)个因子,那么这\(3\)个数一定是\(1\)\(x\)\(\sqrt{x}\),当然如果\(\sqrt{x}\)是一个合数,那么就会有多个,例如\(16\)

所以我们要判断输入的数据是否是完全平方数,以及它的根是否是素数

完全平方数很好判断,判断素数由于数据范围过大,需要线性筛素数。关于筛素数详见:Link

  • 我们考虑有奇数个因数的整数的特点:显然它是一个完全平方数 。而判断完全平方数,只需要判断 \(\sqrt{x}\) 取整的平方(即\(|\sqrt{x}|^2∣\))是否等于 \(x\) 即可。

  • 接下来考虑有三个因数的整数的特点:易知 \(\sqrt{x}\) 不可再分解了,也就是质数,因此我们只需要将 \([1,\sqrt{x}]\) 范围内的所有质数筛出来即可!

  • \(MAX\) 表示 $\sqrt{x}_{max} $ ,\(sqr[i]\) 表示第 \(i\) 个数是完全平方数, \(np[i]\) 表示第 $ i$ 个数不是质数。

Code

#include<cstdio>
#include<cmath>
#define MAX 1000005
#define ll long long
using namespace std;

int n,tot;
ll x;
bool np[MAX+10],sqr[MAX+10];
int p[100005];

void prepare()
{
    for(int i=1;i*i<=MAX;i++)  sqr[i*i]=1;
    for(int i=4;i<=MAX;i+=2)  np[i]=1;
    tot=1;  p[1]=2;  np[0]=np[1]=1;
    for(int i=3;i<=MAX;i+=2)
    {
        if(!np[i])  p[++tot]=i;
        for(int j=1;j<=tot&&i*p[j]<=MAX;j++)
        {
            np[i*p[j]]=1;
            if(i%p[j]==0)  break;
        }
    }
}
int main()
{
    prepare();
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lld",&x);
        ll t=sqrt(x);
        if(t*t==x&&!np[t])  puts("YES");
        else  puts("NO");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lyfoi/p/LiyifengCF203B.html