The question is to give n numbers, and calculate Σ gcd (I, n) (1 <= I <= n ). I feel like a wonderful question. The question of number theory is really hard to think about. I didn't see any relationship with Euler's function.
Very tangled, not in the mood to continue thinking. After reading the discussion, I searched for the answer and found that a buddy had a very good experience. Then I checked my ideas.
The solution to this question is enumeration I (1 <= I <= n). If I | n, then the answer is euler (n/I) * I. In fact, ans = Σ I * euler (n/I) (I <= n and I | n ).
It indicates all the numbers I from 1 to n. If I is a factor of n, I * euler (n/I) is calculated. In the answer, euler is the euler function.
Why. For example, if one to n has m numbers and n has the public largest factor I, then m * I must be added to the answer. The question is how to calculate the number of m.
Because gcd (m, n) = I, we can get that gcd (m/I, n/I) = 1, then m/I is the number in the multiplication group of n/I, then there are a total of euler (n/I) m/I, then
The number of m is euler (n/I ).
The Code is as follows:
# Include <stdio. h>
# Include <math. h>
# Define MAX (6000000)
Bool bPrime [MAX];
Void InitPrime ()
{
Int nMax = sqrt (double) MAX) + 1;
BPrime [0] = bPrime [1] = true;
For (int I = 2; I <= nMax; ++ I)
{
If (! BPrime [I])
{
For (int j = 2 * I; j <MAX; j + = I)
{
BPrime [j] = true;
}
}
}
}
Bool IsPrime (long nN)
{
If (nN <MAX) return! BPrime [nN];
Long nMax = sqrt (double) nN) + 1;
For (int I = 2; I <= nMax; ++ I)
{
If (nN % I = 0)
Return false;
}
Return true;
}
Long Euler (long nN)
{
Long nAns = 1;
// Printf ("nN: % I64d,", nN );
If (IsPrime (nN) nAns = nN-1;
Else
For (int I = 2; I <= nN; ++ I)
{
If (nN % I = 0)
{
NAns * = I-1;
NN/= I;
While (nN % I = 0)
{
NAns * = I;
NN/= I;
}
If (IsPrime (nN ))
{
NAns * = nN-1;
Break;
}
}
}
// Printf ("nAns: % I64d \ n", nAns );
Return nAns;
}
Int main ()
{
Long nN;
InitPrime ();
While (scanf ("% I64d", & nN) = 1)
{
Long nAns = 0;
Long nMax = sqrt (double) nN) + 1e-8;
For (long I = 1; I <= nMax; ++ I)
{
If (nN % I = 0)
{
// Printf ("I: % I64d \ n", I );
NAns + = I * Euler (nN/I );
If (I * I! = NN)
NAns + = (nN/I) * Euler (I );
}
}
Printf ("% I64d \ n", nAns );
}
Return 0;
}