int prime[MAXN];//质数列表
bool isPrime[MAXN];//标记是否为质数(0表示是,1表示不是)
int cnt;//prime表长
/*
对于任意合数m,可写作m=p*k(p为m的最小质因子,k为m/p,m、k>1且为整数,k>p(p为最小质因子,k为其它几个质因子相乘,每个质因子都比p大,所以k>p))
*/
//欧拉筛(使每个合数只被其最小质因数筛去,O(n))
void Euler(int n){
//对于每一个质数p,都一定能枚举倒k*p(因为k>p,外层循环i逐个枚举),所以所有质数m均会被筛掉
for(int i = 2;i <= n;i++){//枚举k,k=i
if(!isPrime[i]) prime[++cnt] = i;//如果不是质数,则存入prime数组
for(int j = 1;j <= cnt;j++){//枚举p,p=prime[j]
if(prime[j] * i > n) break;//超出n则不需要计算
isPrime[prime[j] * i] = 1;//标记合数(i从2开始,所以i,prime[j]都大于1)
if(i % prime[j] == 0) break;
/*如果i % prime[j] == 0,则i=prime[j] * k(k为整数),记此时的j为t
对于i * prime[j],均可写为prime[t] * k * prime[j]
若j < t,则prime[j] < prime[t](质数表是按升序存的(2~n),所以越靠后越大),此时,最小质因数为prime[j]
若j > t,则prime[j] > prime[t],此时,最小质因数为prime[t],prime[j]此时已不再是最小质因数,所以prime[j] * i应该已经被prime[t]筛去,可以直接结束循环
*/
}
}
}
标签:prime,合数,int,代码,最小,C++,质因数,质数,欧拉
From: https://blog.csdn.net/shenshi6666/article/details/142703382