for(int i = 2; i <= 1000000; ++ i)
{
if(!isComp[i])
pv.push_back(i);
for(int k = 0; k < pv.size() && i * pv[k] <= 1000000; ++ k)
{
isComp[i * pv[k]] = 1;
if(i % pv[k] == 0)
break;
}
}
isComp数组代表该数是否为合数 pv是一个存储素数的vector
这个算法对每个合数有且仅有一次访问,他是基于如下规则的:
该合数在算法中被最小素数p1访问到i * pv[k] 其中pv[k]即为p1
证明:假设有合数C=p1*p2*c1,p1 p2为素数且p1为最小素因数,c1为整数
若该合数会被p2访问到,那么C=p2*(p1*c1)
但是p1*c1即为i能整除p1,算法在此步就break掉,无法再对比p1大的p2进行相乘运算
于是i*pv[k]即为该数的最小素因数分解式
根据此分解式可以得出许多结论,包括在O(logn)时间内得到素因子分解,以及在该算法遍历过程中得到欧拉函数Pi(n) ,在此不一一展开