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

 

 

 

转载于:https://www.cnblogs.com/cytus/p/9619479.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值