性质
-
若 x ⩾ 2 x\geqslant 2 x⩾2 ,则 x = p 1 × p 2 × p 3 × p 4 × p 5 × p 6 × . . . × p n x= p_1 \times p_2 \times p_3 \times p_4 \times p_5 \times p_6 \times ... \times p_n x=p1×p2×p3×p4×p5×p6×...×pn
-
威尔逊定理: 若 p p p 为素数,则 ( p − 1 ) ! ≡ − 1 ( m o d p ) (p-1)! \equiv -1 \pmod{p} (p−1)!≡−1(modp) 。 若 ( p − 1 ) ! ≡ − 1 ( m o d p ) (p-1)! \equiv -1 \pmod{p} (p−1)!≡−1(modp) 为素数,则 p p p 为素数。
-
费马定理: 若 a , p a,p a,p 互质且 p p p 为素数, a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1 \pmod{p} ap−1≡1(modp)
-
费马小定理: 若 p p p 为素数, a p ≡ a ( m o d p ) a^{p} \equiv a \pmod{p} ap≡a(modp)
素数的判定
朴素算法
void check(int x)
{
for(int i=2; i*i<=x; i++)
{
if(x%i==0)
{
cout<<"NO"<<endl;
return ;
}
}
if(x==1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
M i l l e r − R a b i n Miller-Rabin Miller−Rabin 素数测试
原理1:费马小定理: 若 p p p 为素数, a p ≡ a ( m o d p ) a^{p} \equiv a \pmod{p} ap≡a(modp)
原理2:二向探测定理: 若 p p p 为素数并 x 2 ≡ 1 ( m o d p ) x^2 \equiv 1 \pmod{p} x2≡1(modp) 则 x = 1 x=1 x=1 或 x = p − 1 x=p-1 x=p−1 。
有 x 2 − 1 ≡ 0 ( m o d p ) x^2 -1 \equiv 0 \pmod{p} x2−1≡0(modp) 。
有 ( x − 1 ) × ( x + 1 ) ≡ 0 ( m o d p ) (x-1)\times (x+1) \equiv 0 \pmod{p} (x−1)×(x+1)≡0(modp) 。
有 x = 1 x=1 x=1 或 x = p − 1 x=p-1 x=p−1 。
-
计算 数字 m , r m,r m,r , n = 2 r + m + 1 n=2^r + m +1 n=2r+m+1
-
选择随机数 A < n A<n A<n ( s r a n d ( t i m e ( N U L L ) ) srand(time(NULL)) srand(time(NULL)) ) ,
-
计算 A 2 i + m ( 1 ≤ i ≤ r ) A^{2^i + m} (1\le i \le r) A2i+m(1≤i≤r) ,若 A 2 i + m m o d n = 1 a n d ( A 2 i − 1 + m = = 1 或 A 2 i − 1 + m = = n − 1 ) {\color{#2CA9E1}{A^{2^i + m} \bmod n=1 \quad and \quad (A^{2^{i-1} + m}==1 \quad \mathsf{\text{或}} \quad A^{2^{i-1} + m}==n-1)}} A2i+mmodn=1and(A2i−1+m==1或A2i−1+m==n−1) 则同过测试,否则 n n n 不为素数
4.计算 A n − 1 m o d n 等于 A 2 r + m m o d n {\color{#2CA9E1}{A^{n-1} \bmod n \quad \mathsf{\text{等于}} \quad A^{2^r + m} \bmod n}} An−1modn等于A2r+mmodn 若值为 1 1 1 则同过测试否则 n n n 不为素数.
- 重复1至4(大概 6 , 7 6,7 6,7 遍即可).
#define ll unsigned long long
namespace Solve
{
ll ksc(ll x,ll y,ll mod)
{
ll res=0;
while(y)
{
if(y&1)
{
res=res+x;
res%=mod;
}
y>>=1;
x=(x+x)%mod;
}
return res;
}
ll ksm(ll xx,ll y,ll mod)
{
__int128 res=1,x=xx;
while(y)
{
if(y%2==1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
bool Miller_Rabin(ll n)
{
if(n==1)return 0;
if(n==2)return 1;
ll m=n-1,r=0;
while(m%2==0)m>>=1,r++;
for(ll i=1; i<=10; i++)
{
ll a=rand()%(n-1)+1;
ll x=ksm(a,m,n),nxt;
for(ll j=1; j<=r; j++)
{
nxt=ksc(x,x,n);
if(nxt==1&&x!=1&&x!=n-1)return 0;
x=nxt;
}
if(x!=1)return 0;
}
return 1;
}
}
质数筛
线性算法,可以求出
void find_prime(int n)
{
int cnt=0;
for(int i=2; i<=n; i++)
{
if(!v[i])
{
p[++cnt]=i;
v[i]=i;
cout<<i<<" ";
}
for(int j=1; p[j]*i<=n&&j<=cnt; j++)
{
v[p[j]*i]=p[j];
if(!(i%p[j]))break;
}
}
cout<<endl;
for(int i=2; i<=n; i++)cout<<i<<" "<<v[i]<<endl;
cout<<endl;
}