51nod 1136 欧拉函数

对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质。
 

输入

输入一个数N。(2 <= N <= 10^9)

输出

输出Phi(n)。

输入样例

8

输出样例

4

欧拉函数φ(n)是求小于n与n互为质数的数的个数,就是最大公因数是1,那么就是n减去与n不互为质数的数,即与n最大公因数>=2的数。对于1肯定只有1。比如1800=2^3*3^2*5^2.2,3,5是质数,
任何一个大于1的数可以分解成质数的幂的乘积,
φ(1800)=1800-1800/2-1800/3-1800/5+1800/(2*3)+1800/(3*5)+1800/(2*5)-1800/(2*3*5),这里是用到容斥定理,跟1800是互质的数肯定能被2,3,5中至少一个数整除,即是他们几个的倍数,
所以1800里有几个数是2的倍数就是1800/2,但是存在既可以整除2也可以整除3的,其他的一样,需要加上,但是又存在同时整除2,3,5的,多加了就要减去。上面那个式子可以合并成
φ(1800)=1800*(1-1/2)*(1-1/3)*(1-1/5)=1800*1/2*2/3*4/5.
然后欧拉函数有一些性质,
对于质数a来说,φ(a)=a-1,显然既然a是质数,其他比他小的都跟他互质。
那么对于正整数k,φ(a^k)=a^k-a^(k-1),显然能整除他的只有质数a,只有一个质数因子,所以减去除以a的即可。
若a,b互质,φ(a*b)=φ(a)*φ(b),这样理解,φ(a)是a以内与a互质的数,显然他们都与b互质,乘上b以内与b互质的数仍然和b互质,也和a互质,就跟a*b互质。
n有m个质数因子p1..pm,φ(n)=(p1^k1-p1^(k1-1))*...*(pm^km-pm^(km-1))=n*(1-1/p1)*...*(1-1/pm).
大概理解不做证明。

代码:
#include <iostream>
#include <cstdio>
#define MAX 100000
using namespace std;
int n;
int main() {
    scanf("%d",&n);
    long long ans = n;
    for(int i = 2;i <= n;i ++) {
        if(n % i == 0) {
            ans = ans * (i - 1) / i;
            while(n % i == 0) n /= i;
        }
    }
    printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/8023spz/p/10010249.html