疑问:关于欧拉函数的(nloglogn)算法。在代码中的部分,不明白为什么这样就可以求出欧拉函数的值
phi[1] = 1;
for (int i = 2; i <= 50001; ++i) if (!phi[i])
{
for (int j = i; j <= 50001; j += i)//这一块地方
{
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i - 1);
}
}
更新:2015.08.24
首先是关于phi数组的定义:小于i且与i互为素数的整数的个数
i 的唯一分解式 : i = p1^a1*p2^a2*p3^a3......(p1 ... pn均为素数)
然后是普通求法是根据容斥原理:phi[i] = i - i / p1 - i / p2 - ...... + i / p1p2 + i / p1p3 + ......
最终简化成:phi[i] = i*( 1 - 1/p1)*(1 - 1/p2)*.......
展开式的每一项,相当于每一次选择1或者-1/pi进行运算,即又变成了未简化前的式子
//注意到简化式中,phi = i*( 1 - 1/p1)*(1 - 1/p2)*......
//在内层循环里枚举素数的倍数,素数倍数的简化式和本身的简化式
//区别在于两处:第一、i的不同;第二、如果本身乘的倍数是素数,
//那么这个倍数就会添加到phi的公式中,即多出来一个(1 - 1/p)
//嘛,这就是原理~
phi[1] = 1;
for (int i = 2; i <= 50001; ++i) if (!phi[i])
{
for (int j = i; j <= 50001; j += i)
{
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i - 1);
}
}