51nod 1106 质数检测——Mr判素数

质数检测一般都是根号n的写法 当然Mr判素数的方法可以实现log的复杂度2333

Mr判素数的话 我们根据费马小定理只要P是素数 那么另一个素数x 满足 x^P-1≡1(mod P) 

同时 x^2%P==1 的解只有 x==1||x==P-1 可以利用这第二个式子做二次探测

利用 2 3 5 7 11 13 17 这七个素数可以保证int内正确性QAQ

当然记得判断2 3 5 7 11 13 17  因为费马小定理成立的条件是 x和P 互质

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int T,n;
int num[7]={2,3,5,7,11,13,17};
LL pmod(LL a,LL b,LL c){
    LL ans=1;
    while(b){
        if(b&1) ans=ans*a%c;
        b>>=1; a=a*a%c;
    }
    return ans;
}
bool calc(LL x,LL P){
    LL ly=P-1,yy,last;
    while(ly%2==0) ly/=2;
    last=yy=pmod(x,ly,P);
    while(ly!=P-1){ 
        yy=yy*yy%P;
        if(yy==1&&last!=1&&last!=P-1) return 0;
        ly*=2; last=yy;
    }
    return yy==1;
}
bool pd(LL n){
    if(n==2||n==3||n==5||n==7||n==11||n==13||n==17) return 1;
    for(int i=0;i<7;i++)if(!calc(num[i],n)) return 0;
    return 1;
}
int main(){
    T=read();
    while(T--){
        n=read();
        if(pd(n)) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
View Code

 

posted @ 2017-10-18 11:33  友人Aqwq  阅读(389)  评论(0编辑  收藏  举报