个人对素数筛分法的原理的理解:任何合数n总存在一个质因子q满足:q<=(int)sqrt(n);
我们可以这样把[2,n]中的合数筛选出来:
因为n=q*p ( q <= ( int ) sqrt( n ) ); 只要对[2,q]内的质数循环,对于每一个质数标记其可达的倍数(合数)(自身除外)
就可以标记出【2,n】中的合数了。
//spoj prime ganerator #include <iostream> #include <cstdio> #include<string> using namespace std; #define N 100005 #define M 31624 #define L 31486 bool comN[M];//composite number int primeList[L]; int numP; void makePrimeList(int upper)//sieve the prime number from the range of [2,upper] { memset(comN,0,sizeof(comN));//0 stands for the number i is prime int p = 2; while(p * p < upper) { //Don't repeat search for (int i = p*p; i < upper; i += p) comN[i] = true;//mark the composite number starts from p*p not p*2 while(comN[++p]);//find a prime number } for (int i = 2; i < M; i ++) { if (comN[i] == false) { primeList[numP ++] = i; } } } bool that[N]; int main() { makePrimeList(M); int t,i; scanf("%d", &t); while(t--) { // if(!i) puts(""); int a, b; scanf("%d%d", &a, &b); if (a == 1) a++; memset(that, 0, sizeof(that)); for (i = 0; i < numP; i ++) { // s的取值范围 2<=s<=int(a / primeList[i]) int s=int(a / primeList[i]); if(s<2)s=2; for (int j = primeList[i] * s ; j <= b; j += primeList[i]) { if (j >= a) { that[j - a] = true; // 把[a, b]内的合数筛掉 } } } for (i = a; i <= b; i ++) { if (that[i-a] == 0 ) { printf("%d/n", i); } } cout<<endl; } return 0; }
这题还可用MR做,不过有点冒险,考虑太多反而会超时!如:a*b%n ,a*b >2^64,不用考虑这种情况。
可是每个案例前都要加上 i == 0 ? : puts(""); 才不用WA,有点费解!
#include <ctime> #include<cstdlib> typedef long long LL ;//__int64 , long long LL multiMod ( LL a , LL b , LL n ) {//s=(a*b)(mod n) (n<2^62) // return ( (a%m) * (b%m) ) % m; // this will overflow! a %= n ; b %= n ; LL s = 0 ; while( b ) { if( b & 1 ) { s += a ; if( s >= n ) s -= n ; } a <<= 1 ; b >>= 1 ;//a*b=(a*2)*(b/2) if(a >= n ) a -= n ; } return s ; } LL powerMod ( LL s , LL u , LL n ) { s %= n ; LL tmp = 1 ; while ( u ) { if ( u & 1 ) tmp *= s , tmp %= n ; s = s * s % n ; u >>= 1 ; } return tmp ; } bool witness ( LL s , LL n ) { LL u = n - 1 ; int t = 0 ; while ( ( u & 1 ) == 0 ) u >>= 1 , t ++ ; LL x = powerMod ( s , u , n ) ; while ( t -- ) { LL tmp = x ; x = x * x % n ; if ( x == 1 ) { if ( tmp == n - 1 || tmp == 1 ) return false ;//may be prime else return true ;//composite } } return true ; //composite } bool millerRabin ( LL n , const int times = 3 ) { if ( n == 2 ) return true ; if ( ( n & 1 ) == 0 || n < 2 ) return false ; int i = times ; while ( i -- ) { LL s = rand ( ) % ( n - 1 ) + 1 ; if ( witness ( s , n ) ) return false ; } return true ; }
参考:http://www.cnblogs.com/lijunle/archive/2010/11/18/1880343.html