Cod sursa(job #174588)

Utilizator vlad.maneaVlad Manea vlad.manea Data 8 aprilie 2008 23:47:29
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.54 kb
#include <stdio.h>
#define nmax 1000000

unsigned long long N, P, ans, prod, N2, answer;

unsigned long long prim[nmax], sol[nmax];

void read()
{
  freopen("frac.in", "r", stdin);

  scanf("%llu%llu", &N, &P);
}

void write()
{
  freopen("frac.out", "w", stdout);

  printf("%llu\n", ans);
}

void back(unsigned long long prod, unsigned long long count, unsigned long long where, unsigned long long pos, unsigned long long x)
{
  unsigned long long i;

//  if (prod <= x)
  {
    if (count > 0)
    {
      if (count % 2)
        answer += x-x/prod;
      else
        answer -= x-x/prod;
    }
  }
//  else
//    return;

  for (i = pos; i <= prim[0]; ++i)
  {
    sol[where] = prim[i];
//    if(prod*prim[i] <= x)
      back(prod * prim[i], count+1, where+1, i+1, x);
    sol[where] = 0;
  }
}

unsigned long long howmany(unsigned long long x)
{
  answer = 0;

  // cu principiul includerii si excluderii
  // aflu factorii primi ai lui x

  back(1, 0, 1, 1, x);

  return answer;
}

void solve()
{
  unsigned long long i, x, l, r, m;

  // aflu factorii primi ai lui N
  for (N2 = N, i = 2; N2 > 1; ++i)
    for (; N2 % i == 0; N2 /= i)
      if (i != prim[prim[0]])
        prim[++prim[0]] = i;

  for (x = 2; howmany(x) < P; x <<= 1);

  for (l = 1, r = x; l <= r; )
  {
    m = (l + r)>>1;

    x = howmany(m);

    if (x >= P)
    {
      r = m-1;
      ans = m;
    }
    else
    {
      l = m+1;
    }
  }
}

int main()
{
  read();

  solve();

  write();

  return 0;
}