pojPseudoprime numbers (fast power)

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 

this question means that input two numbers p, a, output yes when that p is not a prime number and pow (a, p)% p == a, otherwise output no
idea: so long as the basic fast power can make to this question.
Fast Power: The idea is to pow (a, p) of p 2 into a plurality of multiple forms of adding, the pow (a, p) = pow (a, c1) * pow (a, c2) *. ... * pow (a, cn) , where p = c1 + c2 + .. + cn; using bitwise operators
can easily implement this operation.

int Fastpow(int a,int p){

Fastpow int (A int, int p) {
Long Long Base int = A;
Long Long int RES = 1;
the while (p) {
IF (p & 1) // if p is the last digit binary representation is 1, for the true, false otherwise
RES = Base * / *, RES = RES% MOD * /;
Base * = Base;
/ * Base = Base MOD%; * /
p >> 1; // p binary representation of the backward one, the last one just treated to remove the p
}
return RES;
}

 

The second is a power of expression fast recursive

Fastpow int (int A, P int) {
IF (P ==. 1) return A;
Long Long Fastpow int TEMP = (A, P / 2)% P;
IF (P% 2 ==. 1) return * TEMP TEMP% p * a% p; // here omitted if the first p will answer Wrong
the else return TEMP TEMP% * p;
}

 

Finally, attach the AC codes:

#include<iostream>
#include<cstdio>
using namespace std;
long long int p;
int Fastpow(int a,int n){
long long int m=n,base=a;
long long int res=1;
while(m){
if(m&1){
res=res*base%p;
}
base=(base*base)%p;
m>>=1;
}
return res;
}
/*int Fastpow(int a,int n){
if(n==1) return a;
long long int temp=Fastpow(a,n/2)%p;
if(n%2==1) return temp*temp%p*a%p;
else return temp*temp%p;
}*/
int main(){
long long int a,c[100000];
while(~scanf("%lld%lld",&p,&a)){
if(p==0&&a==0) return 0;
int plug=0;
for(int i=2;i*i<=p;i++)
if(p%i==0) plug=1;
if(plug==0) {
printf("no\n");
continue;
}
//cout<<Fastpow(a,p)<<endl;
if(Fastpow(a,p)==a) printf("yes\n");
else printf("no\n");
}
}

Determining whether this is the most basic is a prime number, using the trial division, a fast algorithm is given below using a sieve prime number, less time-consuming than the above that a lot:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=31700;
const long long int maxn1=1e9+10;
int Fastpow(int a,int p){
long long int m=p,base=a;
long long int res=1;
while(m){
if(m&1){
res=res*base%p;
}
base=(base*base)%p;
m>>=1;
}
return res;
}
int main(){
long long int p,a;
int c[maxn],prim[maxn],j=0;
memset(c,0,sizeof(c));
for(int i=2;i*i<maxn1;i++){
if(c[i]==0){
prim[j]=i,j++;
for(int k=i*i;k<maxn;k+=i)
c[k]=-1;
}
}
while(~scanf("%lld%lld",&p,&a)){
if(p==0&&a==0) return 0;
int plug=1;
for(int i=0;i<j&&prim[i]<p;i++)
if(p%prim[i]==0) plug=0;
if(plug==1) {
printf("no\n");
continue;
}
if(Fastpow(a,p)==a) printf("yes\n");
else printf("no\n");
}
}

Guess you like

Origin www.cnblogs.com/sunjianzhao/p/11461512.html