现在的位置: 首页 > 算法 > 正文

poj 3641&hdu 1905(伪素数判定)

2018年12月27日 算法 ⁄ 共 1382字 ⁄ 字号 评论关闭

题意:给出p,a问p是不是以a为底的伪素数,如果p不是素数判断,是否a^p%p==a






#include<iostream>  
#include<algorithm>  
#include<math.h>  
#include<stdio.h>    
#include<string.h>    
#include<time.h>    
#include<stdlib.h>    
typedef __int64 LL;   
LL a,b,sum;   
const int S=20;//随机算法判定次数,S越大,判错概率越小     
//***************Miller_Rabin 算法进行素数测试***************    
int cmp(void const *a,void const *b)  
{  
    if(*(LL *)a>*(LL *)b)  
        return 1;  
    else return -1;  
}  
LL mult_mod(LL a,LL x,LL n)//返回(a*x) mod n,a,x,n<2^63    
{    
    a%=n;x%=n;    
    LL ret=0;    
    while(x)    
    {    
        if(x&1){ret+=a;if(ret>=n)ret-=n;}    
        a<<=1;    
        if(a>=n)a-=n;    
        x>>=1;    
    }    
    return ret;    
}    
LL pow_mod(LL a,LL x,LL n)//返回a^x mod n    
{    
    if(x==1)return a%n;    
    int bit[70],k=0;    
    while(x)    
    {    
        bit[k++]=(x&1?1:0);    
        x>>=1;    
    }    
    LL ret=1;    
    for(--k;k>=0;k--)    
    {    
       ret=mult_mod(ret,ret,n);    
       if(bit[k])ret=mult_mod(ret,a,n);    
    }    
    return ret;    
}    
bool judge(LL a,LL n,LL x,LL t)//以a为基,n-1=x*2^t,检验n是不是合数    
{    
    LL ret=pow_mod(a,x,n),flag=ret;    
    for(LL i=1;i<=t;i++)    
    {    
        ret=mult_mod(ret,ret,n);    
        if(ret==1&&flag!=1&&flag!=n-1)return true;    
        flag=ret;    
    }    
    if(ret!=1)return true;    
    return false;    
}    
bool Miller_Rabin(LL n)    
{    
    if(n==2||n==5||n==7||n==11)return true;    
    if(n%2==0||n%5==0||n%7==0||n%11==0)return false;    
    LL x=n-1,t=0;    
    while((x&1)==0)x>>=1,t++;    
    bool flag=true;    
    if(t>=1&&(x&1)==1)    
    {    
        for(int i=1;i<=S;i++)    
        {    
            LL a=rand()%(n-1)+1;    
            if(judge(a,n,x,t)){flag=true;break;}    
            flag=false;    
        }    
    }    
    if(flag)return false;    
    else return true;    
}
int main()
{
	int i,j;
	LL p,a,b;
	while(scanf("%I64d %I64d",&p,&a),p||a)
	{
		if(Miller_Rabin(p)){printf("no\n");continue;}
		b=pow_mod(a,p,p);
		if(b==a)
			printf("yes\n");
		else printf("no\n");
	}
	return 0;
}

抱歉!评论已关闭.