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 isa. 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 ≤ 1,000,000,000 and 1 < a < p, determine whether or not p is a base-a pseudoprime.
Input contains several test cases followed by a line containing "0 0". Each test case consists of a line containing p and a. 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
Output for Sample Input
no no yes no yes yes
用欧拉筛选法求出[1,31623]之间的素数,对与p在这个范围内的,可以直接判断是不是素数,大于该范围的,用p除以[1,31623]之间的素数
用快速求幂算法求mod
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import java.util.ArrayList;
public class Main implements Runnable{
private static final boolean DEBUG = false;
private static final int N = (int)Math.sqrt(1000000000) + 1;
private Scanner cin;
private PrintWriter cout;
private int p, a;
private ArrayList<Integer> vPrime = new ArrayList<Integer>();
private boolean[] vis;
private void init()
{
try {
if (DEBUG) {
cin = new Scanner(new BufferedInputStream(
new FileInputStream("e:\\uva_in.txt")));
} else {
cin = new Scanner(new BufferedInputStream(System.in));
}
cout = new PrintWriter(new OutputStreamWriter(System.out));
sieve();
} catch (Exception e) {
e.printStackTrace();
}
}
private void sieve()
{
vis = new boolean[N];
vis[0] = vis[1] = true;
for (int i = 2; i < N; i++) {
if (!vis[i]) {
vPrime.add(i);
}
for (int j = 0; j < vPrime.size() && i * vPrime.get(j) < N; j++) {
vis[i * vPrime.get(j)] = true;
if (i % vPrime.get(j) == 0) break;
}
}
}
private long exp(long a, long n, long b)
{
long product = 1;
while (n != 0) {
if ((n & 1) != 0) product = product * a % b;
a = (a % b) * (a % b) % b;
n >>= 1;
}
return product;
}
private boolean input()
{
p = cin.nextInt();
a = cin.nextInt();
if (p == 0 && a == 0) return false;
return true;
}
private boolean check(int n)
{
if (n < N) return vis[n];
for (int i = 0; i < vPrime.size(); i++) {
int tmp = vPrime.get(i);
if (n % tmp == 0) return true;
}
return false;
}
private void solve()
{
if (check(p) && exp(a, p, p) == (long)a) cout.println("yes");
else cout.println("no");
cout.flush();
}
public void run()
{
init();
while (input()) {
solve();
}
}
public static void main(String[] args)
{
new Thread(new Main()).start();
}
}