Pagini recente » Borderou de evaluare (job #3124049) | Cod sursa (job #234712)
Cod sursa(job #234712)
/*
* http://mathworld.wolfram.com/TotientFunction.html
* http://infoarena.ro/forum/?topic=33.0
*
* p - prime number
* t(p^e) = (p - 1) * p^(e - 1)
* p - prime number, p does not divide a
* t(p^e * a) = t(p^e) * t(a) = (p - 1) * p^(e - 1) * t(a)
*
* This way we can easily find t(n+1) knowing a single prime divisor of n+1
* and all t(1), t(2), ... t(n)
*/
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
long N;
ifstream in("fractii.in");
in >> N;
in.close();
long *firstDivisor = new long[N + 1];
memset(firstDivisor, 0, (N + 1) * sizeof(*firstDivisor));
long long *totient = new long long[N + 1];
totient[1] = 1;
for (long i = 2; i <= N; i++) {
long m = i + i;
while (m <= N) {
if (firstDivisor[m] == 0)
firstDivisor[m] = i;
m += i;
}
if (firstDivisor[i] == 0) {
totient[i] = i - 1;
}
else {
long pe = firstDivisor[i];
int e = 1;
while (i % (pe * firstDivisor[i]) == 0) {
pe *= firstDivisor[i];
e++;
}
if (pe == i) {
// i is power of a prime number
totient[i] = (firstDivisor[i] - 1)
* pe / firstDivisor[i];
}
else {
totient[i] = totient[pe] * totient[i / pe];
}
}
}
delete[] firstDivisor;
long long solutions = 1; // the fraction 1/1
// totient only has relative primes smaller than i
// count both (i / totient[i]) and (totient[i] / i)
for (long i = 2; i <= N; i++)
solutions += 2 * totient[i];
delete[] totient;
ofstream out("fractii.out");
out << solutions << endl;
out.close();
return 0;
}