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