质数
质数
试除法判断质数 O(sqrt(n))
时间复杂度是根号n
bool is_prime(int x)
{
if(x < 2) return false;
for(int i = 2; i <= x / i; i ++) // i <= x/i 要取等
{
if(x % i == 0) return false;
}
return true;
}
试除法分解质因数 O(sqrt(n))
时间复杂度是根号n
一个数x一定有且只有一个大于sqrt(x)的质因数(如果有两个大于根号x的质因数,相乘结果大于x,显然不成立)
下面的这个函数每次的i都可以保证一定是质数。每次x都变小了,如果i能被2到i-1的数整除,那么x一定能被2到i-1中的数整除,因为x是i的倍数(n能被i整除)。在迭代到i之前,<=i-1的合数已经被肢解了
// 按照质因数从小到大的顺序输出每个质因数的底数和指数
void divide(int x)
{
for(int i = 2 ; i <= x / i ; i ++)
{
if(x % i == 0)
{
int s = 0; // 保存质因数的指数
while(x % i == 0)
{
x /= i;
s ++;
}
cout << i << ' ' << s << endl;
}
}
if(x > 1) cout << x << ' ' << 1 << endl; // x一定有且只有一个大于sqrt(x)的质因子
}
筛素数(线性筛法) O(n)
线性筛素数的核心是:根据最小质因子来筛除
int primes[N],cnt,n;
bool st[N];
// 筛2~n中的素数
for(int i = 2 ; i <= n ; i ++)
{
if(!st[i]) primes[cnt ++] = i; // 如果i没有被筛除,i为素数
for(int j = 0; primes[j] * i <= n; j ++) // 因为筛的是2~n的,大于n就没有意义了
{
st[primes[j]*i] = true; // 根据最小质因子去筛除
if(i % primes[j] == 0) break; // primes[j]是i的最小质因子,primes[j]*i的最小质因子不再是primes[j+1]*i,就不能再根据最小质因子筛素数,break
}
}
rds_blogs

浙公网安备 33010602011771号