LibreOJ#143 质数判定 [Miller_Rabin]
质数判定
题目描述
判定输入的数是不是质数。
输入格式
若干行,一行一个数 x。
行数不超过 $1.5\times 10^4$
输出格式
对于输入的每一行,如果 x是质数输出一行 Y,否则输出一行 N。
样例
样例输入
1
2
6
9
666623333
样例输出
N
Y
N
N
Y
数据范围与提示
$1\leq x\leq 10^{18}$
欢迎hack(如果你不是管理员,可以在题目讨论区发帖)。
分析:
Miller_Rabin模板,被卡了好久。
具体的Miller_Rabin算法博主就不再讲了,注意要考虑到一些细节,然后$LibreOJ$卡时间,不能用$\log n$的乘法,需要用快速乘。
Code:
//It is made by HolseLee on 10th Sep 2018 //LibreOJ#143 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll n,a[6]={2,3,5,7,61,24251}; inline ll mul(__int128 x,__int128 y,__int128 m) { return (__int128)(x*y)%m; } inline ll power(ll x,ll y,ll m) { ll ret=1; x%=m; while( y ) { if( y&1 ) ret=mul(ret,x,m); y>>=1; x=mul(x,x,m); } return ret; } inline bool miller_rabin(ll u) { if( u==2 ) return 1; if( !(u&1) || u==1 || u==46856248255981 ) return 0; u-=1; int cnt=0; ll x,pre; while( !(u&1) ) u>>=1,cnt++; for(int i=0; i<=5; ++i) { if(n==a[i])return 1; if(n%a[i]==0)return 0; x=power(a[i],u,n); pre=x; for(int j=1; j<=cnt; ++j) { x=mul(x,x,n); if( x==1 && pre!=n-1 && pre!=1 ) return 0; pre=x; } if( x!=1 ) return 0; } return 1; } int main() { while( scanf("%lld",&n)!=EOF ) { if( miller_rabin(n) ) puts("Y"); else puts("N"); } return 0; }
蒟蒻写博客不易,如果有误还请大佬们提出
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com