poj3641 快速幂+米勒罗宾

Description

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-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

 

1、p不是素数
2、a的p次幂除以p的余数等于a

判断下就好了

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mp make_pair
#define ss second
#define ff first
#define pb push_back
template 
void read(T &x)
{
    static char ch;bool neg = false;
    while(!isdigit(ch = getchar())) (ch == '-') && (neg = true);
    for(x = ch - '0'; isdigit(ch = getchar()); x = x * 10 + ch - '0');
    (neg) &&(x = -x);
}
template void read(T &head, U &... tail){read(head), read(tail...);}
typedef unsigned long long ull;
typedef long long ll;
const int maxn=1e5+5;
ll p,a;
const int _time=5;
ll multi(ll a, ll b, ll mod) {
    ll ret = 0;
    while(b) {
        if(b & 1) ret = ret + a;
        if(ret >= mod) ret -= mod;
        a = a + a;
        if(a >= mod) a -= mod;
        b >>= 1;
    }
    return ret;
}
ll quick_pow(ll a, ll b, ll mod) {
    ll ret = 1;
    while(b) {
        if(b & 1) ret = multi(ret, a, mod);
        a = multi(a, a, mod);
        b >>= 1;
    }
    return ret;
}
bool Miller_Rabin(ll n) {
    ll u = n - 1, pre, x;
    int i, j, k = 0;
    if(n == 2 || n == 3 || n == 5 || n == 7 || n  == 11) return true;
    if(n == 1 || (!(n % 2)) || (!(n % 3)) || (!(n % 5)) || (!(n % 7)) || (!(n % 11)))
        return false;
    for(; !(u & 1); k++, u >>= 1);
    srand(32165847);
    for(i = 0; i < _time; i++) {
        x = rand() % (n - 2) + 2;
        x = quick_pow(x, u, n);
        pre = x;
        for(j = 0; j < k; j++) {
            x = multi(x, x, n);
            if(x == 1 && pre != 1 && pre != (n - 1))
                return false;
            pre = x;
        }
        if(x != 1) return false;
    }
    return true;
}

void work()
{
    ll ans=quick_pow(a,p,p);
    if(!Miller_Rabin(p)&&ans==a) printf("yes\n");
    else printf("no\n"); 
}

int main()
{
    //int T;read(T);while(T--)
    while(~scanf("%lld %lld",&p,&a))
    {
        if(p==0&&a==0) break;
        work();
    }
    
    return 0;
}

 

你可能感兴趣的:(题目)