Cod sursa(job #224597)

Utilizator daniel.dumitranDaniel Dumitran daniel.dumitran Data 30 noiembrie 2008 04:12:10
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.46 kb
#include <stdio.h>

#include <vector>

int n, i;
std::vector<int> primes, local_primes;
int prod, sign, sum;
long long total;
unsigned k;

void back() {
  if (k == local_primes.size()) {
    if (!sign) sum += i / prod; else sum -= i / prod;
    return;
  }

  k++; back(); k--;
  
  prod *= local_primes[k];
  sign = sign ^ 1;
  k++; back(); k--;
  sign = sign ^ 1;
  prod /= local_primes[k];
}

int main() {

  FILE *f;
  f = fopen("fractii.in", "rt");
  fscanf(f, "%d", &n);
  fclose(f);
  
  for (i = 2; i <= n; ++i) {
    int nr = i;
    local_primes.clear();

    for (std::vector<int>::const_iterator it = primes.begin();
         it != primes.end() && (*it) * (*it) <= nr; ++it) {
      int j = *it;
      if (!(nr % j)) {
        local_primes.push_back(j);
        nr /= j;
        while (!(nr % j))
          nr /= j;
      }
    }

    if (nr > 1)
      local_primes.push_back(nr);

    if ((nr == i) && ((long long)nr * (long long)nr <= (long long)n)) {
      primes.push_back(nr);
    }

#if 0
    // local primes should be sorted
    for (unsigned j = 1; j < local_primes.size(); ++j)
      if (local_primes[j - 1] >= local_primes[j])
        printf("bad1\n");
#endif

    prod = 1; k = 0; sign = 0; sum = 0;
    back();

#if 0
    // Sum should always be positive
    if (sum <= 0)
      printf("bad2\n");
#endif

#if 0
    printf("%d : %d\n", i, sum);
#endif

    total += 2 * sum;
  }

  f = fopen("fractii.out", "wt");
  fprintf(f, "%lld\n", total + 1);
  fclose(f);

  return 0;
}