标签:sqrt tin continue 处理 理论 names using 偶数 ++
入门级筛素数--试除法,复杂度O(n^2)
bool rmprime( long long n ) { for(long long i = 2; i <= sqrt(n) ; i++) if(n%i == 0) return false; return true; }
学了一段时间算法以后,应该会了解到筛法求素数,复杂度略高于O(n)
#include<iostream> #include<cstring> using namespace std; const int MAXN = 500000; bool isp[MAXN]; int p[MAXN]; int cnt = 0;//保存素数个数 void getp() { for(int i = 1; i < MAXN; i++) isp[i] = 1 ; //默认全部素数 for(int i = 2; i < MAXN; i++){ if(!isp[i]) continue; //如果不是素数就continue掉 p[cnt++] = i; for(int j = i * 2 ; j < MX; j += i) isp[j] = 0;//记录,往后滚处理 } } int main(){ getp(); for(int i = 0; i < cnt; i++) printf("%d ",p[i]); return 0; }
当然,不难发现,如果MaX值过大的话,不只空间会炸,而且从头开始扫很玄学,是不怎么可取的。
于是引入MILLER RABIN算法。可以单独判断一个大数是否素数,但是不保证正确。我们只能通过多次执行算法让这个错误的概率很小。//不过幸运的是,除非你是非酋王,这个算法一般都是不会出问题的。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <map> using namespace std; const int times = 20; int number = 0; map<long long, int>m; long long Random( long long n ) //生成[ 0 , n ]的随机数 { return ((double)rand( ) / RAND_MAX*n + 0.5); } long long q_mul( long long a, long long b, long long mod ) //快速计算 (a*b) % mod { long long ans = 0; while(b) { if(b & 1) { b--; ans =(ans+ a)%mod; } b /= 2; a = (a + a) % mod; } return ans; } long long q_pow( long long a, long long b, long long mod ) //快速计算 (a^b) % mod { long long ans = 1; while(b) { if(b & 1) { ans = q_mul( ans, a, mod ); } b /= 2; a = q_mul( a, a, mod ); } return ans; } bool witness( long long a, long long n )//miller_rabin算法的精华 {//用检验算子a来检验n是不是素数 long long tem = n - 1; int j = 0; while(tem % 2 == 0) { tem /= 2; j++; } //将n-1拆分为a^r * s long long x = q_pow( a, tem, n ); //得到a^r mod n if(x == 1 || x == n - 1) return true; //余数为1则为素数 while(j--) //否则试验条件2看是否有满足的 j { x = q_mul( x, x, n ); if(x == n - 1) return true; } return false; } bool miller_rabin( long long n ) //检验n是否是素数 { if(n == 2) return true; if(n < 2 || n % 2 == 0) return false; //如果是2则是素数,如果<2或者是>2的偶数则不是素数 for(int i = 1; i <= times; i++) //做times次随机检验 { long long a = Random( n - 2 ) + 1; //得到随机检验算子 a if(!witness( a, n )) //用a检验n是否是素数 return false; } return true; } int main( ) { long long tar; while(cin >> tar) { if(miller_rabin( tar )) //检验tar是不是素数 cout << "Yes, Prime!" << endl; else cout << "No, not prime.." << endl; } return 0; }
标签:sqrt tin continue 处理 理论 names using 偶数 ++
原文地址:http://www.cnblogs.com/shuri/p/7638588.html