素数
打印素数表,超级素数1亿以内,时间复杂度2.4s
#include <cstdio> #include <time.h> const int N = 100000000; bool isprime[N]; int p[100000000]; int suprime[100]; int np; void sup(int n){ //判断超级素数 int t=n; if(n<10) {suprime[np++]=n ,printf("%d,",n);return;} if(n<20) return ; while(n){ n/=10; if(isprime[n]) return; } suprime[np++]=t; printf("%d,",t); } void prime(int n) //生成一个我们想要的小范围的素数表,用于素数判断 { int np = 0; for (int i = 2; i <= n; i++) { if (!isprime[i]) p[np++] = i,sup(i); for (int j = 0; j < np && p[j]*i <= n; j++) { isprime[p[j]*i] = 1; if( i % p[j] == 0) break; } } printf("\n\n\n\n%d\n",np); } int main(){ freopen("data.out","w",stdout); int n; long long start,end; scanf("%d",&n); start = clock(); prime(n); end = clock(); printf("//运行耗时%.2f秒\n",(end-start)*1.0/1e3); }
判断素数:
费马素数测试
费马小定理:
有N为任意正整数,P为素数,且N不能被P整除(显然N和P互质),
则有:
N^P%P=N(即:N的P次方除以P的余数是N)
公式变形: (N^P-N)%P=0 ==》 N(N^(P-1)-1)%P=0
因为 N(N^(P-1)-1) 是p和n公倍数
设M为是p*n的倍数。
则N(N^(P-1)-1) = M*N*P ==》N^(P-1)-1 =M*P ==》(N^(P-1)-1)%P=0 ==》N^(P-1)%P=1 ( 积模分解公式)
最终推出 定理:N^(P-1)%P=1
利用这个公式
求解:
int Montgomery(int n,int p,int m) //蒙格马利快速幂模算法,用于后面素数判断 { //快速计算(n^e)%m的值,即逐次平方法 int k=1; n%=m; while(p!=1) { if(0!=(p&1)) k=(k*n)%m; n=(n*n)%m; p>>=1; } return(n*k)%m; } bool IsPrime(int n) //利用蒙格马利快速幂模算法来判断素数 { if ( n < 2 ) { // 小于2的数即不是合数也不是素数 return false; } for (int i=0;i<np;++i) { // 按照素数表中的数对当前素数进行判断 if (1!=Montgomery(p[i],n-1,n))//蒙格马利算法 return false; } return true; }