Cod sursa(job #2264153)

Utilizator preda.andreiPreda Andrei preda.andrei Data 19 octombrie 2018 20:38:03
Problema Fractii Scor 40
Compilator c-64 Status done
Runda Arhiva de probleme Marime 1.55 kb
#include <stdio.h>

#define NMAX 1000000
#define PRIMESMAX 80000

long long int tots[NMAX + 1];
char not_prime[NMAX + 1];
int primes[PRIMESMAX];

int GetPrimes(int limit)
{
    int prime_count = 0;
    for (int i = 2; i <= limit; i += 1) {
        if (!not_prime[i]) {
            primes[prime_count] = i;
            prime_count += 1;

            for (long long int j = 1LL * i * i; j <= limit; j += i) {
                not_prime[j] = 1;
            }
        }
    }
    return prime_count;
}

long long int Tot(int n)
{
    if (tots[n] != 0) {
        return tots[n];
    }

    int cn = n;
    long long int res = 1;

    for (int i = 0; n > 1; i += 1) {
        int prime = primes[i];
        int power = 1;

        while (n % prime == 0) {
            n /= prime;
            power *= prime;
        }
        if (power > 1) {
            res *= Tot(power);
        }
    }
    return tots[cn] = res;
}

void Preprocess(int limit)
{
    int prime_count = GetPrimes(limit);
    for (int i = 0; i < prime_count; i += 1) {
        int prime = primes[i];
        tots[prime] = prime - 1;

        long long int power = 1LL * prime * prime;
        while (power <= limit) {
            tots[power] = power / prime * (prime - 1);
            power *= prime;
        }
    }
}

int main()
{
    FILE *fin = fopen("fractii.in", "r");
    FILE *fout = fopen("fractii.out", "w");

    int n;
    fscanf(fin, "%d", &n);

    Preprocess(n);

    long long int res = 1;
    for (int i = 2; i <= n; i += 1) {
        res += Tot(i) * 2;
    }

    fprintf(fout, "%lld\n", res);
    return 0;
}