poj_3641_Pseudoprime numbers

Fermat's theorem states that for any prime number p and for any integer a > 1, ap = a (mod p). That is, if we raise a to the pth power and divide by p, the remainder is a. Some (but not very many) non-prime values of p, known as base-a pseudoprimes, have this property for some a. (And some, known as Carmichael Numbers, are base-a pseudoprimes for all a.)

Given 2 < p ≤ 1000000000 and 1 < a < p, determine whether or not p is a base-a pseudoprime.

Input

Input contains several test cases followed by a line containing "0 0". Each test case consists of a line containing p and a.

Output

For each test case, output "yes" if p is a base-a pseudoprime; otherwise output "no".

Sample Input

3 2
10 3
341 2
341 3
1105 2
1105 3
0 0

Sample Output

no
no
yes
no
yes
yes


题意:费马定理给出a^p=a mod p(p为素数),一些合数也有类似的状况,判断输入p,a
先判断 p是否为素数,后判断是否满足定理
#include<iostream>
#include<cstdio>
#define LL long long
#define N 100000
using namespace std;
int prime[N];
int pn=0;
bool vis[N];
LL pow(LL a,LL n,LL mod)
{
    LL base=a,ret=1;
    while(n)
    {
        if(n&1) ret=(ret*base)%mod;
        base=(base*base)%mod;
        n>>=1;
    }
    return ret%mod;
}
bool judge(int n)
{
    for(int i=0;prime[i]*prime[i]<=n;i++)
    {
        if(n%prime[i]==0)
            return 1;
    }
    return 0;
}
int main()
{
    for (int i = 2; i < N; i++) {
        if (vis[i]) continue;
        prime[pn++] = i;
        for (int j = i; j < N; j += i)
            vis[j] = 1;
    }
    int a,p;
    while(~scanf("%d%d",&p,&a),a&&p)
    {
        if(!judge(p)){
            puts("no");
            continue;
        }
        if(pow(a,p,p)%p==a)
            puts("yes");
        else
            puts("no");

    }
}

  

posted @ 2017-11-26 20:12  会飞的雅蠛蝶  阅读(130)  评论(0编辑  收藏  举报