素数
性质
-
若 $ x\geqslant 2 $ ,则 $ x= p_1 \times p_2 \times p_3 \times p_4 \times p_5 \times p_6 \times ... \times p_n $
-
威尔逊定理: 若 $ p $ 为素数,则 $ (p-1)! \equiv -1 \pmod{p} $ 。 若 $ (p-1)! \equiv -1 \pmod{p} $ 为素数,则 $ p $ 为素数。
-
费马定理: 若 $ a,p $ 互质且 $ p $ 为素数, $ a^{p-1} \equiv 1 \pmod{p} $
-
费马小定理: 若 $ p $ 为素数, $ a^{p} \equiv a \pmod{p} $
素数的判定
朴素算法
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;
}
$ Miller-Rabin $ 素数测试
原理1:费马小定理: 若 $ p $ 为素数, $ a^{p} \equiv a \pmod{p} $
原理2:二向探测定理: 若 \(p\) 为素数并 \(x^2 \equiv 1 \pmod{p}\) 则 \(x=1\) 或 \(x=p-1\) 。
有 \(x^2 -1 \equiv 0 \pmod{p}\) 。
有 \((x-1)\times (x+1) \equiv 0 \pmod{p}\) 。
有 \(x=1\) 或 \(x=p-1\) 。
-
计算 数字 \(m,r\) , \(n=2^r + m +1\)
-
选择随机数 \(A<n\) ( \(srand(time(NULL))\) ) ,
-
计算 \(A^{2^i + m} (1\le i \le r)\) ,若 \({{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)}}\) 则同过测试,否则 \(n\) 不为素数
4.计算 \({{A^{n-1} \bmod n \quad \mathsf{\text{等于}} \quad A^{2^r + m} \bmod n}}\) , 若值为 \(1\) 则同过测试否则 \(n\) 不为素数.
- 重复1至4(大概 \(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;
}

浙公网安备 33010602011771号