Practice:
I can't find it.
Only considering that there are CI m for gcd (m, n) = I. The answer to this formula is Σ (CI * I)
Gcd (m, n) = I <=> gcd (M/I, n/I) = 1
Find the number of M/I in gcd (M/I, n/I) = 1, which is the definition of Euler's function PHI ().
So it is converted to Phi (N/I)
Enumeration of each M | n for Phi (N/I) The answer is Σ (PHI (N/I) * I)
How to enumerate each M | n?
It is easy to enumerate all integers from 1 to SQRT (N). All the approximate numbers are j | n (n/J) | n
This is done.
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef long long LL;
const int nmax = 50005;
int prime[nmax], flag[nmax];
int plen;
void mkprime() {
int i, j;
memset(flag, -1, sizeof(flag));
for (i = 2; i < nmax; i++) {
if (flag[i]) {
for (j = i + i; j < nmax; j += i)
flag[j] = 0;
}
}
for (i = 2, plen = 0; i < nmax; i++)
if (flag[i])
prime[plen++] = i;
}
int getPhi(int n) {
int i, te, phi;
te = (int) sqrt(n * 1.0);
for (i = 0, phi = n; (i < plen) && (prime[i] <= te); i++) {
if (n % prime[i] == 0) {
phi = phi / prime[i] * (prime[i] - 1);
while (n % prime[i] == 0) {
n /= prime[i];
}
}
}
if (n > 1) {
phi = phi / n * (n - 1);
}
return phi;
}
void solve(int n) {
int i, j, te;
LL sum;
te = static_cast<int>(sqrt(1.0 * n));
for (i = 1, sum = 0; i <= te; i++) {
if (n % i == 0) {
j = n / i;
sum += i * getPhi(j);
if (i != j) {
sum += j * getPhi(i);
}
}
}
printf("%I64d\n", sum);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n;
mkprime();
while (~scanf("%d", &n)) {
solve(n);
}
return 0;
}
[Analysis]:
Set F (n) = Σ gcd (I, n)
Inference ~ The maximum number of N and N is P, which is equal)
Therefore, we can obtain F (n) = Σ PHI (N Div p) * P (p | N)
Set n = (P1 ^ k1) (P2 ^ K2)... (PN ^ kN) (P1, p2.. PN ε prime)
Therefore, F (n) = f (P1 ^ k1) f (P2 ^ K2)... f (PN ^ kN)
So we only need to find F (PI ^ KI ).
F (P ^ K) = Σ [(P ^ c) φ( P ^ (k-C)] (0 <= C <= k) due to the small size of Σ K, we can enumerate C
For PHI (P ^ I) (p ε prime) There is PHI (P ^ I) = (p-1) P ^ (I-1) but there is PHI (1) = 1
#include<stdio.h>
#include<string.h>
#include<math.h>
#define LL long long
#define nmax 46345
int prime[nmax], plen;
void mkprime() {
int i, j;
memset(prime, -1, sizeof(prime));
for (i = 2; i < nmax; i++) {
if (prime[i]) {
for (j = i + i; j < nmax; j += i) {
prime[j] = 0;
}
}
}
for (i = 2, plen = 0; i < nmax; i++) {
if (prime[i]) {
prime[plen++] = i;
}
}
}
int getPow(int a, int b) {
int res;
res = 1;
while (b) {
if (b & 1) {
res = res * a;
}
b >>= 1;
a = a * a;
}
return res;
}
int getpPhi(int p, int c) {
if (c == 0) {
return 1;
}
return (p - 1) * getPow(p, c - 1);
}
LL cal(int p, int c) {
int i;
LL sum, temp;
for (i = 0, sum = 0, temp = 1; i <= c; i++) {
sum += temp * getpPhi(p, c - i);
temp *= p;
}
return sum;
}
void solve(int n) {
int i, te, cnt;
LL res;
te = (int) (sqrt(n * 1.0));
for (i = 0, res = 1; (i < plen) && (prime[i] <= te); i++) {
if (n % prime[i] == 0) {
cnt = 0;
while (n % prime[i] == 0) {
cnt++;
n /= prime[i];
}
res = res * cal(prime[i], cnt);
}
}
if (n > 1) {
res = res * cal(n, 1);
}
printf("%I64d\n", res);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n;
mkprime();
while (scanf("%d", &n) != EOF) {
solve(n);
}
return 0;
}