质数与和数的定义
质数与和数:在>=2的自然数中定义了一些自然数为质数(仅能被1和其自身整除),而其他的一些数就被称为和数(与质数相对,除了能被1和其自身整除以外还能被其他自然数整除)
一、质数的判定---试除法
bool is_prime(int x)
{if(x<=1)return false;for(int i=2;i<=x/i;i++) //不要用开方函数或者i*i小于x。开方函数慢,i*i可能越界{if(x%i==0)return false;}return true;
}
二、分解质因数---试除法
for(int i=2;i<=x/i;i++) //i <= x / i:将x的所有<=sqrt(x)的质因子除去(其中x是可能会变化的<即不断减小>,这相当于是一种优化)
{int num=0;while(x%i==0){num++;x/=i;}if(num!=0)cout<<i<<" "<<num<<endl;
}
if(x>1)cout<<x<<" "<<1<<endl; // x的质因子最多只包含一个大于 根号x 的质数。如果有两个,这两个因子的乘积就会大于 x,矛盾
//而当x>1时则说明 x 的质因子中包含一个大于 根号x 的质数(其中x是可能会变化的<即不断减小>,这相当于是一种优化)
三、质数的筛选
①埃式筛法
for(int i=2;i<=n;i++) //i从数字2开始遍历
{if(st[i])continue; //如果i被标记的话,说明它不是质数,则跳过这个数else{primes[idx++]=i; //如果i没有被标记的话,说明它是质数,则将它存到质数数组中去for(int j=2*i;j<=n;j+=i) //并且将i在n内的所有倍数进行标记(因为可以确定它们都已经不可能是质数了){st[j]=true;}}
}
②线性筛法
for(int i=2;i<=n;i++) //i从数字2开始遍历
{if(!st[i])primes[idx++]=i; //如果i没有被标记的话,说明它是质数,则将它存到质数数组中去for(int j=0;primes[j]*i<=n;j++){st[primes[j]*i]=true;if(i%primes[j]==0)break;}
}