1.埃氏筛法
for(int i=2;i<=n;i++)
{
if(fl[i]==0) prime[++tot]=i;
for(int j=1;j<=tot&&i*prime[j];j++)
{
fl[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
prime数组存的就是所求的质数
2.威尔逊定理
p是质数 (p-1)!≡-1(mod p) 这两个条件可以互推
3.费马小定理
若p是质数,a为正整数,且a与p互质,则
证明过程用到了威尔逊定理
4.Miller-Rabim 素数测试
输入n,判断n是否为质数,如果n为质数,那一定满足费马小定理,所以可以随机输出几个a,判断是否满足费马小定理,如果都满足,那基本上就是质数了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
int n;
int ff(int a,int m,int p)
{
int s=1;
while(m!=0)
{
if(m%2==1) s=s*a%p;
a=a*a%p;
m>>=1;
}
return s;
}
bool Miller_Rabin(int n)
{
if(n==2) return true;
for(int i=1;i<=10;i++)
{
int a=rand()%(n-2)+2;
if(ff(a,n,n)!=a) return false;
//if(ff(a,n-1,n)!=1) return false; 利用费马小定理
}
return true;
}
int main()
{
srand(time(NULL));
cin>>n;
if(Miller_Rabin(n)==true) cout<<"yes";
else cout<<"no";
return 0;
}
5.欧拉定理
若n,a为正整数,且n,a互质,则:
求n以内的欧拉函数
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int n=1e6+5;
ll phi[n],p[n],sum[n],tot;
bool f[n];
void getphi()
{
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(f[i]==false)
{
p[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++)
{
if(i*p[j]>n) break;
f[i*p[j]]=true;
if(i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
else phi[i*p[j]]=phi[i]*(p[j]-1);//欧拉定理 φ(a*b)=φ(a)*φ(b)
}
}
}
int main()
{ int a;
getphi();
for(int i=2;i<=n;i++) sum[i]=sum[i-1]+phi[i];
for(int i=1;;i++)
{
cin>>a;
if(a==0) return 0;
else cout<<sum[a]<<endl;
}
return 0;
}