辗转相除法求最大公约数 及 素数筛选
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;
}
}
}