Cod sursa(job #191526)

Utilizator cata00Catalin Francu cata00 Data 27 mai 2008 04:47:28
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <stdio.h>

// precompute primes up to 1000
int precomp[10000];
int nPrecomp;

int n;
int primes[10000];
int numPrimes;

int relativelyPrime(int n) {
  int origN = n;
  numPrimes = 0;
  int i = 0;
  while (n > 1 && i < nPrecomp && precomp[i] * precomp[i] <= n) {
    if (n % precomp[i] == 0) {
      primes[numPrimes++] = precomp[i];
      do {
	n /= precomp[i];
      } while (n % precomp[i] == 0);
    }
    i++;
  }
  if (n > 1) {
    primes[numPrimes++] = n;
  }
//   printf("%d: ", origN);
//   for (int k = 0; k < numPrimes; k++) {
//     printf("%d ", primes[k]);
//   }

  int multiplier = origN;
  int result = 1;
  for (int k = 0; k < numPrimes; k++) {
    multiplier /= primes[k];
    result *= primes[k] - 1;
  }
  //  printf("| multiplier: %d result: %d", multiplier, result * multiplier);

  //printf("\n");
  return result * multiplier;
}

void precomputePrimes() {
  for (int i = 2; i <= 1000; i++) {
    int k = 0;
    int stillPrime = 1;
    while (k < nPrecomp && stillPrime) {
      if (i % precomp[k] == 0) {
	stillPrime = 0;
      }
      k++;
    }
    if (stillPrime) {
      precomp[nPrecomp++] = i;
    }
  }
}

int main(void) {
  precomputePrimes();

  FILE* f = fopen("fractii.in", "rt");
  fscanf(f, "%d", &n);
  fclose(f);

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

  f = fopen("fractii.out", "wt");
  fprintf(f, "%lld\n", result);
  fclose(f);
  return 0;
}