Pagini recente » Profil RockMan | moisil-2017 | Istoria paginii utilizator/nicky_dumitrache | Cod sursa (job #2022123) | Cod sursa (job #2092502)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
uint64_t euler(uint64_t n);
bool is_prime(uint64_t n);
uint64_t phi(uint64_t n);
uint64_t *cr(uint64_t n, uint64_t *dx);
uint64_t dx;
uint64_t *c;
int main(void)
{
FILE *in = fopen("fractii.in", "r");
FILE *out = fopen("fractii.out", "w");
if(in != NULL && out != NULL)
{
uint64_t n;
uint64_t s = 0;
fscanf(in, "%llu", &n);
c = cr(n, &dx);
uint64_t i = 1;
for(; i <= n; i++)
{
s += euler(i);
}
fprintf(out, "%llu\n", (2 * s) - 1);
free(c);
fclose(in);
fclose(out);
}
else
{
printf("Error\n");
}
return 0;
}
uint64_t *cr(uint64_t n, uint64_t *dx)
{
uint64_t psize = 10;
uint64_t pgrow = 5;
uint64_t pidx = 0;
uint64_t *primes = malloc(sizeof(uint64_t) * psize);
uint64_t *vector = malloc(sizeof(uint64_t) * (n + 3));
if(vector != NULL && primes != NULL)
{
uint64_t i = 0;
for(; i <= n; i++)
{
vector[i] = i;
}
vector[1] = 0;
primes[pidx++] = 2;
i = 2;
for(; i <= n; i += 2)
{
vector[i] = 0;
}
uint64_t last = 2;
while(1)
{
bool found = false;
uint64_t j = last + 1;
for(; j <= n; j++)
{
if(vector[j])
{
if((pidx + 1) >= psize)
{
psize += pgrow;
primes = realloc(primes, sizeof(uint64_t) * psize);
if(primes == NULL)
{
printf("Failed to realloc\n");
exit(EXIT_FAILURE);
}
}
primes[pidx++] = vector[j];
found = true;
last = j;
break;
}
}
if(found)
{
uint64_t mark = vector[j];
uint64_t inc = vector[j];
for(; mark <= n; mark += inc)
{
vector[mark] = 0;
}
}
else
{
break;
}
}
*dx = pidx;
free(vector);
return primes;
}
else
{
printf("FAILED TO INIT\n");
}
}
bool is_prime(uint64_t n)
{
if((n == 1) || (n % 2 == 0 && n != 2))
{
return false;
}
else
{
uint64_t i = 2;
for(; i * i <= n; i++)
{
if(n % i == 0)
{
return false;
}
}
return true;
}
}
uint64_t euler(uint64_t n)
{
if(is_prime(n))
{
return n - 1;
}
else
{
return phi(n);
}
}
uint64_t phi(uint64_t n)
{
double calc = n;
uint64_t i = 0;
for(; i < dx; i++)
{
if(n % c[i] == 0)
{
calc *= (1.0 - (double)(1.0 / c[i]));
}
}
return (uint64_t)calc;
}