素数筛选 及 最小公倍数

来源:互联网 发布:java软件开发工作描述 编辑:程序博客网 时间:2024/05/21 10:50

辗转相除法求最大公约数 及 素数筛选

GCD与LCM

求a,b的最大公约数--gcd

求a,b的最小公倍数--lcm

inline unsigned int gcd(unsigned int a, unsigned int b){      while( b ^= a ^= b ^= a %= b ); return a;  }  inline unsigned int lcm(unsigned int a,unsigned int b){      return a / gcd( a, b ) * b;  }

2进制版本GCD

int gcd(int x, int y)   {        int i, j;        if( x == 0 ) return y;        if( y == 0 ) return x;        for(i = 0; 0 == (x & 1) ; ++i) x >>= 1;        for(j = 0; 0 == ( y & 1) ;++j) y >>= 1;        if( j < i ) i = j;        while( true ){                if( x < y ) x ^= y, y ^= x, x ^= y;                   if(0 == ( x -= y ) ) return y << i;                 while(0 == ( x & 1 )) x >>= 1;        }}


线性素数筛选

线性筛选,如果num为素数,则isNotPrime[num] = 0,primeList为素数集合,PrimeCtr为集合大小

素数下标从1开始到PrimeCtr

const int maxn = 100;  int isNotPrime[maxn+5];int primeList[maxn], PrimeCtr;  void getPrime()  {      PrimeCtr = 0;  isNotPrime[0] = isNotPrime[1] = 1;      for(int i = 2; i <= maxn; ++i)      {          if( !isNotPrime[i] ) primeList[ ++PrimeCtr ] = i;          for(int j = 1; j <= PrimeCtr && i * primeList[j] <= maxn; j++)          {              isNotPrime[i * primeList[j]] = true;              if( i % primeList[j] == 0 ) break;          }      }  } 


区间筛选

下标从0开始到PrimeCtr-1

#include<iostream>  #include<algorithm>  #include<cmath>  using namespace std;   const int maxn = 100000;    int  PrimeList[maxn], PrimeCtr;   bool IsNotPrime[maxn]; /* IsNotPrime[i] = 1表示i + L这个数不是素数. */ void SegmentPrime(int L, int U)  {       int i,j;       int SU = sqrt( 1.0 * U );       int d = U - L + 1;       for(i = 0; i < d; ++i) IsNotPrime[i] = 0; /*一开始全是素数*/       for(i=(L % 2 != 0); i < d; i += 2)            IsNotPrime[i] = 1; /*把偶数的直接去掉*/       for (i = 3; i <= SU; i += 2)       {             if (i > L && IsNotPrime[i - L]) continue;              /* IsNotPrime[i - L] == 1说明i不是素数. */            j = (L / i) * i; /* j为i的倍数,且最接近L的数. */            if (j < L) j += i;             if (j == i) j += i; /*i为素数,j = i说明j也是素数,所以直接 + i*/             j=j-L;             for(; j < d; j += i) IsNotPrime[j] = 1;              /* 说明j不是素数(IsNotPrime[j - L] = 1). */       }       if (L <= 1) IsNotPrime[1 - L] = 1;       if (L <= 2) IsNotPrime[2 - L] = 0;       PrimeCtr = 0;       for (i = 0; i < d; i++)             if (!IsNotPrime[i])                    PrimeList[PrimeCtr++] = i + L;  }      int main()  {      SegmentPrime(5,100);      for(int i = 0; i < PrimeCtr;++i)  /* 注意素数id是从0到PrimeCtr-1 */      printf("%d\n",PrimeList[i]);  } 

朴素筛选素数

const int maxn = 0xfff;void getPrime(){bool isPrime[maxn];    memset(isPrime, true, sizeof(isPrime));  isPrime[0] = isPrime[1] = false;    for(int i = 2; i < max; i++)  {      if(isPrime[i])      {          for(int j = 2 * i; j < max; j += i)              isPrime[j] = false;      }  }}