Problem I: 约素
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1844 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
5
64 7
911 233
1080 13
1024 11
20170211 1913
Sample Output
YES
NO
NO
YES
NO
题意:中文题面,自己看。
解题思路:乍一看,好像很难,但是仔细看一下题目,发现p是质数,利用这个条件,加上唯一分解定理,就是一个数一定能分成若干个质数的乘积,
那么有
所以要想n的约数的个数为p,p是一个质数,那么n最多一个质因子,所以n必须为某一质数的p - 1次方,才能满足条件,因为p >= 3,所以我们只需要预处理1e6次方以内的素数就行。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e6;
typedef long long ll;
ll n,p;
bool prime[maxn];
ll ans[maxn];
int res;
ll quick_mod(ll x,ll i)
{
ll ans = 1;
while(i)
{
if(i&1) ans = ans*x;
i >>= 1;
x = x*x;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
memset(prime,true,sizeof(prime));
res = 0;
for(int i = 2; i <= maxn; i++)
{
if(prime[i])
{
res++;
ans[res] = i;
}
for(int j = 1; i*ans[j] <= maxn&&j <= res; j++)
{
prime[i*ans[j]] = false;
if(i%ans[j] == 0) break;
}
}
while(T--)
{
scanf("%lld%lld",&n,&p);
bool flag = false;
ll x;
for(int i = 1; i <= res; i++)
{
if(n%ans[i] == 0)
{
flag = true;
x = ans[i];
break;
}
}
if(flag)
{
ll sum = quick_mod(x,p - 1);
if(sum == n)
{
printf("YES\n");
}
else printf("NO\n");
}
else printf("NO\n");
}
return 0;
}
/**************************************************************
Problem: 4274
User: creatorx
Language: C++
Result: Accepted
Time:224 ms
Memory:10252 kb
****************************************************************/