Problem I: 约素
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1847 Solved: 480
Description
判断一个正整数n的约数个数是否为p,其中p是素数。
Input
第一行给测试总数T(T <= 10000)。
接下来有T行,每行有两个数字n(1 <= n <= 1000000000)和p(2 < p <= 1000000000)。Output
每组测试数据输出一行,如果n的约数个数是p,输出“YES”,否则输出“NO”。
Sample Input
564 7911 2331080 131024 1120170211 1913
Sample Output
YES
NO
NO
YES
NO
首先根据给的约数的个数p,我们知道根据唯一分解定理,如果一个数分解的质因子个数为a1,a2,a3,a4.....那么约数的个数为(a1+1)*(a2+1)*(a3+1)*(a4+1)...
然后约数的个数是一个素数,也就是说不可能存在乘积的形式,那么这个数必定是某个素数的p-1次方。根据这个就好办多了,然后题目中的p>2,然后就是p-1>1了,所以至少是平方的,这样我们可以把素数的范围从1e9降低到根下1e9。这样我们就可以求出相应的素数来了,然后枚举这些素数,看看有没有符合条件的,有就YES,没有就NO。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
int pw(int a,int b)
{
int sum=1,base=a;
while(b)
{
if(b&1)sum*=base;
base*=base;
b>>=1;
}
return sum;
}
bool prim[MAXN];
int prim1[MAXN];
int cnt=0;
void getPrim()
{
int n=sqrt(1000000000+0.5);
for(int i=2;i<=n;++i)
{
if(!prim[i])
{
prim1[cnt++]=i;
for(int j=i*2;j<=n;j+=i)prim[j]=1;
}
}
}
int main()
{
int t;
scanf("%d",&t);
int n,m;
getPrim();
while(t--)
{
scanf("%d%d",&n,&m);
m--;
int flag=0;
for(int i=0; i<cnt; ++i)
{
if(pw(prim1[i],m)==n)
{
puts("YES");
flag=1;
break;
}
}
if(!flag)puts("NO");
}
return 0;
}