Euler function --POJ-2480

Topic Link

Subject to you ask sigma gcd (i, N) 1 <= i <= N

To know a first equation gcd (i, N) = p => gcd (i / p, N / p) = 1

In example N = 12

gcd = 12 and the number 1 is the number of prime numbers, which is the Euler function values ​​12, 12 and the GCD of 1,5,7,11

= Gcd number 2 contains the 12/2 = 6 Euler function value, that is, 12 2, 10 gcd

gcd = 3 contains the number of 12/3 = 4 Euler function values, i.e. 3, 9 and 12 gcd

Thus from i = 1, i * i <= n, n% i == 0 found all i * euler (n / i) has been found most of the gcd

The rest is there gcd contains several prime numbers multiplied

Can know that gcd (i, N) are all factors N, divisor Well

Some of these factors than √n large, some smaller than √n

By the previous formula, our idea is to find all possible N gcd = P, cumulative P * euler (N / P)

We loop i = 1, i * i <= n The process of finding N% i == 0, the i found this factor is small is equal to √N

However, if i * i <N, then N / i N must be greater than a factor of √N and also

Therefore we find these cycles correspond to two factors accumulating i

Topic Code

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long LL;
LL euler(LL n){
    LL ans=n;
    for(LL i=2;i*i<=n;i++){
        if(n%i==0){
            ans=ans/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        ans=ans/n*(n-1);
    return ans;
}
int main(){
    LL n;
    while(~scanf("%lld",&n)){
        LL sum=0;
        for(LL i=1;i*i<=n;i++)
        if(n%i==0){
            sum+=i*euler(n/i);
            if(i*i<n)sum+=(n/i)*euler(i);
        }
        printf("%lld\n",sum);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/helman/p/11354558.html