Pagini recente » Cod sursa (job #1506316) | Cod sursa (job #1622324) | Cod sursa (job #2489356) | Cod sursa (job #1004619) | Cod sursa (job #2355139)
#include <fstream>
#include <cmath>
#define SIZE 1000000
#define ALLOCATED SIZE+10
using namespace std;
ifstream cin("fractii.in");
ofstream cout("fractii.out");
short prime[ALLOCATED], phiCalculated[ALLOCATED];
int phi[ALLOCATED];
int main() {
int n, i;
long long sphi;
cin >> n;
for (i = 1; i <= n; i++)
{
phiCalculated[i] = 0;
}
prime[1] = 0;
prime[2] = 1;
//numerele pare altele decat 2 nu sunt prime
for (i = 4; i <= n; i+=2) {
prime[i] = 0;
}
//numerele impare ar putea fi prime
for (i = 3; i <= n; i+=2)
{
prime[i] = 1;
}
//aplicam ciurul lui Eratostene peste numerele impare
int l = sqrt(n);
for (i = 3; i <= l; i+=2) {
if (prime[i]) {
for (int j = 2 * i; j <= n; j+=i) {
prime[j] = 0;
}
}
}
phi[1] = 0;
for (i=2; i<=n; i++) {
if (prime[i]) {
//phi(n) = n-1 daca n este prim
phi[i] = i - 1;
phiCalculated[i] = 1;
//si pentru puterile numarului prim avem formula
for (long long j = i; j*i <= n; j*=i) {
phi[i*j] = j * phi[i];
phiCalculated[i*j] = 1;
}
} else {
if (!phiCalculated[i]) {
// pentru numerele compuse folosim cealalta formula
int d = 2;
//gasim cel mai mic divizor prim al numarului
while (i%d) {
d++;
}
int a, b = i;
//pe care il extragem la maxim
while (b%d==0) {
b /= d;
}
a = i / b;
//avem garantia ca a si b vor fi prime intre ele conform acestei strategii
phi[i] = phi[a] * phi[b];
phiCalculated[i] = 1;
}
}
}
sphi = 0;
for (i = 2; i <= n; i++)
{
sphi += phi[i];
}
cout << 2 * sphi + 1;
cin.close();
cout.close();
return 0;
}