2017浙江理工大学校赛I题

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
****************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值