您的位置:首页 > 其它

欧拉函数[已解决]

2015-08-15 01:32 253 查看
起因:[UVA 10820]Send a Table

疑问:关于欧拉函数的(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);
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: