标签:Miller ll 素数 要么 ans include 定理 Rabin
先说下伪素数的概念,费马小定理的逆不成立的合数成为伪素数,即满足a的x-1mod x=1但不是素数。
通常我们判断奇素数(2肯定是素数)由费马小定理与二次剩余定理得到,1的(x-1)/2=1modx
所以对上述底数a要么为1,要么为-1(取模后)所以我们把x-1进行不断二分,在这些2的m次中要么全为1,要么中间有一个-1,之后全为1,这样条件下,它大概率是素数,在2的64次以内,他人已经为我们找好了检验素数的a,只要全部满足,必为素数。
a: 2, 325, 9375, 28178, 450775, 9780504, 1795265022
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<string.h>
#include<vector>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
using namespace std;
ll qpow(ll a,ll b,ll p){
ll ans=1;
while(b){
if(b&1)ans=(__int128)ans*a%p;
a=(__int128)a*a%p;
b>>=1;
}
return ans;
}
bool is_prime(ll x){
if(x<3)return x==2;
if(x%2==0)return false;
ll A[]={2,325,9375,28178,450775,9780504,1795265022},d=x-1,r=0;
while(d%2==0)
d/=2,++r;
for(int j=0;j<7;j++){
ll v=qpow(A[j],d,x);
if(v<=1||v==x-1)continue;
for(int i=0;i<r;i++){
v=(__int128)v*v%x;
if(v==x-1&&i!=r-1){
v=1;
break;
}
if(v==1)return false;
}
if(v!=1)return false;
}
return true;
}
int main(){
int t;
cin>>t;
ll n;
while(t--){
cin>>n;
if(is_prime(n))cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
标签:Miller,ll,素数,要么,ans,include,定理,Rabin 来源: https://blog.csdn.net/qq_50812688/article/details/119078674
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。