Cod sursa(job #1465937)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 28 iulie 2015 12:24:55
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.32 kb
#include <stdio.h>

#define MAX_PRIMES 11
#define START_STEP (1ULL << 61)

typedef unsigned long long ull;

ull factors[MAX_PRIMES];
int cntFactors;

static inline void breakFactors(ull n) {
  cntFactors = 0;

  if (!(n & 1)) {
    factors[cntFactors++] = 2;
    n /= (n & -n);
  }
  for (register unsigned i = 3; i * i <= n; i += 2) {
    ull q = n / i;
    if (!(n - q * i)) {
      factors[cntFactors++] = i;
      do {
        n = q;
        q = n / i;
      } while (!(n - q * i));
    }
  }
  if (n != 1) {
    factors[cntFactors++] = n;
  }
}

static inline ull cntPinex(ull A) {
  ull q = A;

  for (register int i = (1 << cntFactors) - 1; i; i--) {
    ull prod = 1;
    int cnt = 0;
    for (register int j = 0; j < cntFactors; j++) {
      if (i & (1 << j)) {
        cnt++;
        prod *= factors[j];
      }
    }
    prod = A / prod;
    q += prod ^ ((prod ^ -prod) & -(cnt & 1));
  }
  return q;
}

int main(void) {
  FILE *f = fopen("frac.in", "r");
  ull n, p;
  ull q, step;

  fscanf(f, "%llu%llu", &n, &p);
  fclose(f);

  breakFactors(n);

  q = START_STEP;
  step = START_STEP >> 1;
  while (step) {
    q -= (step & -(cntPinex(q - step) >= p));
    step >>= 1ULL;
  }

  f = fopen("frac.out", "w");
  fprintf(f, "%llu\n", q);
  fclose(f);
  return 0;
}