Cod sursa(job #1822761)

Utilizator TincaMateiTinca Matei TincaMatei Data 5 decembrie 2016 15:27:09
Problema Frac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.48 kb
#include <cstdio>

const int MAX_X = 1000000;
const int MAX_PRIME = 80000;
bool ciur[MAX_X];
long long prime[MAX_PRIME];
long long desc[20];

long long pinex(long long a, long long b) {
  int d, pr, bits;
  long long prod, rez;
  d = 0;
  pr = 0;
  while(prime[d] * prime[d] <= b) {
    if(b % prime[d] == 0) {
      desc[pr] = prime[d];
      while(b % prime[d] == 0)
        b = b / prime[d];
      ++pr;
    }
    ++d;
  }
  if(b > 1) {
    desc[pr] = b;
    ++pr;
  }

  rez = 0LL;
  for(int i = 0; i < (1 << pr); ++i) {
    prod = 1LL;
    bits = 0;
    for(int j = 0; j < pr; ++j)
      if(1 << j & i) {
        ++bits;
        prod = prod * desc[j];
      }
    if(bits % 2 == 0)
      rez = rez + a / prod;
    else
      rez = rez - a / prod;
  }
  return rez;
}

long long search(long long st, long long dr, long long p, long long n) {
  long long mid, rez;
  while(dr - st > 1) {
    mid = (st + dr) / 2;
    rez = pinex(mid, n);
    if(rez <= p)
      st = mid;
    else
      dr = mid;
  }
  return st;
}

int main() {
  int top;
  long long a, b, p, n;

  for(int d = 2; d * d <= MAX_X; ++d)
    if(!ciur[d])
      for(int i = d * d; i <= MAX_X; i = i + d)
        ciur[i] = true;

  top = 0;
  for(int d = 2; d <= MAX_X; ++d)
    if(!ciur[d]) {
      prime[top] = d;
      top++;
    }
  FILE *fin = fopen("frac.in", "r");
  fscanf(fin, "%lld%lld", &n, &p);
  fclose(fin);
  FILE *fout = fopen("frac.out", "w");
  fprintf(fout, "%lld", search(0, 20, p - 1, n) + 1);
  fclose(fout);
  return 0;
}