Problem p02660 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef long long LL;
const int e[40] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
                   5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8};
const int mp[16] = {1,  3,  5,  7,   11,  15,  21,  33,
                    35, 55, 77, 105, 165, 231, 385, 1155};
const int results[16] = {1, 0, 0, 0, 0, 3, 3, 3, 5, 5, 7, 3, 3, 3, 5, 3};
const LL UnUseMethod = 1e9 + 7;
const unsigned long LLONG = 18446744073709551615U;
LL count[2] = {0}, Box[1000] = {0}, sz = 0;
LL IN(void) {
  LL x = 0;
  short f = 0, c = getchar();
  while (c < 48 || c > 57) {
    f ^= c == 45, c = getchar();
  }
  while (c > 47 && c < 58) {
    x = x * 10 + c - 48, c = getchar();
  }
  return f ? -x : x;
}
LL GCD(LL a, LL b) { return !b ? a : GCD(b, a % b); }
LL Mult(LL x, LL y, LL mod) {
  LL temp = x * y - (LL)((long double)x / mod * y + 1e-8) * mod;
  return temp < 0 ? temp + mod : temp;
}
LL BinaryModularPower(LL base, LL pow, LL mod) {
  LL x = 1;
  while (pow) {
    if (pow & 1) {
      x = Mult(x, base, mod);
    }
    base = Mult(base, base, mod);
    pow >>= 1;
  }
  return x;
}
void Exp(LL x, LL y) {
  count[1] = 0;
  while (!(x % y)) {
    count[1]++;
    x /= y;
  }
  count[0] = x;
  return;
}
int MillerRabin(const LL a) {
  if (a == 2)
    return 1;
  if (a % 2 == 0 || a == 1)
    return 0;
  static int pr[7] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
  LL u = a - 1, t = 0, p = 1;
  while (!(u & 1)) {
    u >>= 1;
    t++;
  }
  for (int i = 0; i < 7; ++i) {
    p = pr[i] % a;
    if (!p)
      return 1;
    LL x = BinaryModularPower(p, u, a);
    if (x == 1)
      continue;
    for (int j = 0; x != a - 1 && j < t; ++j) {
      x = Mult(x, x, a);
      if (x == 1)
        return 0;
    }
    if (x == a - 1)
      continue;
    return 0;
  }
  return 1;
}
LL Pseudo(const LL x) { return (LL)((long double)pow(x, 0.5)); }
int PerfectSquare(const LL x) {
  if (x < 0)
    return 0;
  else {
    LL y = Pseudo(x);
    return x == y * y;
  }
}
int PerfectCube(const LL x) {
  LL z = (LL)cbrt(x);
  return x == z * z * z;
}
LL iter(const LL x, const int k, const int lim, const int divisor) {
  int i, j;
  LL bits, temp = GCD(k, x), sq = Pseudo(k * x), cutoff, p0, q0 = 1, p1, q1, Q,
           rootQ = 0;
  cutoff = Pseudo(2 * sq) / divisor, p1 = sq;
  q1 = (k * x - p1 * p1);
  if (temp != 1)
    return temp;
  if ((k * x) >> 62)
    return 1;
  if (!q1) {
    temp = GCD(x, p1);
    return temp == x ? 1 : temp;
  }
  for (i = 0; i < lim; i++) {
    temp = sq + p1 - q1, Q = 1;
    if (temp >= q1)
      Q += temp / q1;
    p0 = Q * q1 - p1;
    q0 = q0 + Q * (p1 - p0);
    if (q1 < 2 * k * cutoff) {
      temp = q1 / GCD(q1, 2 * k);
      if (temp < cutoff)
        Box[sz++] = temp;
    }
    bits = 0, temp = q0;
    while (!(temp & 1)) {
      bits++, temp >>= 1;
    }
    if (!(bits & 1) && ((temp & 7) == 1)) {
      rootQ = Pseudo(q0);
      if (PerfectSquare(q0)) {
        for (j = 0; j < sz; ++j) {
          if (Box[j] == rootQ)
            break;
        }
        if (j == sz)
          break;
      }
    }
    temp = sq + p0 - q0, Q = 1;
    if (temp >= q0) {
      Q += temp / q0;
    }
    p1 = Q * q0 - p0, q1 = q1 + Q * (p0 - p1);
    if (q0 < 2 * k * cutoff) {
      temp = q0 / GCD(q0, 2 * k);
      if (temp < cutoff)
        Box[sz++] = temp;
    }
  }
  if (rootQ == 1)
    return 1;
  if (i == lim)
    return 1;
  q0 = rootQ, p1 = p0 + rootQ * ((sq - p0) / rootQ);
  q1 = (k * x - p1 * p1) / q0;
  for (j = 0; j < lim; j++) {
    Q = 1, temp = sq + p1 - q1;
    if (temp >= q1)
      Q += temp / q1;
    p0 = Q * q1 - p1, q0 = q0 + Q * (p1 - p0);
    if (p0 == p1) {
      q0 = q1;
      break;
    }
    temp = sq + p0 - q0, Q = 1;
    if (temp >= q0)
      Q += temp / q0;
    p1 = Q * q0 - p0, q1 = q1 + Q * (p0 - p1);
    if (p0 == p1)
      break;
  }
  temp = GCD(q0, x);
  if (temp == x)
    temp = 1;
  return temp;
}
LL SQUFOF(LL x) {
  LL y;
  if (MillerRabin(x))
    return x;
  if (PerfectSquare(x))
    return Pseudo(x);
  if (PerfectCube(x))
    return (LL)cbrt(x);
  for (int i = 1; i < 20000; i *= 4) {
    for (int k = 0; k < 16; k++) {
      if (x == mp[k])
        return results[k];
      if (LLONG / mp[k] <= x)
        continue;
      y = iter(x, mp[k], 300 * i, 1);
      if (y == 1 || y == x)
        continue;
      return y;
    }
  }
  return 1;
}
int main(void) {
  LL a = 0, p = 1, q = -1, N = IN();
  if (N <= 1)
    return puts("0"), 0;
  Exp(N, 2);
  a = e[count[1]];
  N = count[0];
  Exp(N, 3);
  a += e[count[1]];
  N = count[0];
  while (q * q <= UnUseMethod) {
    p += 6, q += 6;
    Exp(N, p);
    a += e[count[1]];
    N = count[0];
    Exp(N, q);
    a += e[count[1]];
    N = count[0];
  }
  if (N <= UnUseMethod) {
    if (N > 1) {
      a++;
    }
    return printf("%lld\\n", a), 0;
  }
  if (MillerRabin(N)) {
    a++;
    return printf("%lld\\n", a), 0;
  }
  while (N >= UnUseMethod) {
    p = SQUFOF(N);
    while (p < q)
      p = SQUFOF(p);
    while (!MillerRabin(p))
      p = SQUFOF(p);
    Exp(N, p);
    a += e[count[1]];
    N = count[0];
  }
  if (MillerRabin(N)) {
    a++;
  }
  return printf("%lld\\n", a), 0;
}

Error: TLE

Fixed submission:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef long long LL;
const int e[40] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
                   5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8};
const int mp[16] = {1,  3,  5,  7,   11,  15,  21,  33,
                    35, 55, 77, 105, 165, 231, 385, 1155};
const LL UnUseMethod = 1e9 + 7;
const unsigned long LLONG = 18446744073709551615U;
LL count[2] = {0};
LL IN(void) {
  LL x = 0;
  short f = 0, c = getchar();
  while (c < 48 || c > 57) {
    f ^= c == 45, c = getchar();
  }
  while (c > 47 && c < 58) {
    x = x * 10 + c - 48, c = getchar();
  }
  return f ? -x : x;
}
LL GCD(LL a, LL b) { return !b ? a : GCD(b, a % b); }
LL Mult(LL x, LL y, LL mod) {
  LL temp = x * y - (LL)((long double)x / mod * y + 1e-8) * mod;
  return temp < 0 ? temp + mod : temp;
}
LL BinaryModularPower(LL base, LL pow, LL mod) {
  LL x = 1;
  while (pow) {
    if (pow & 1) {
      x = Mult(x, base, mod);
    }
    base = Mult(base, base, mod);
    pow >>= 1;
  }
  return x;
}
LL f(LL x, LL mod, LL c) { return (Mult(x, x, mod) + c) % x + 1; }
void Exp(LL x, LL y) {
  count[1] = 0;
  while (!(x % y)) {
    count[1]++;
    x /= y;
  }
  count[0] = x;
  return;
}
int MillerRabin(const LL a) {
  if (a == 2)
    return 1;
  if (a % 2 == 0 || a == 1)
    return 0;
  static int pr[7] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
  LL u = a - 1, t = 0, p = 1;
  while (!(u & 1)) {
    u >>= 1;
    t++;
  }
  for (int i = 0; i < 7; ++i) {
    p = pr[i] % a;
    if (!p)
      return 1;
    LL x = BinaryModularPower(p, u, a);
    if (x == 1)
      continue;
    for (int j = 0; x != a - 1 && j < t; ++j) {
      x = Mult(x, x, a);
      if (x == 1)
        return 0;
    }
    if (x == a - 1)
      continue;
    return 0;
  }
  return 1;
}
LL SQUFOF(LL n) {
  LL D, Po, P, Prev, Q, Qrev, q, b, r, s = (LL)(pow(n + 0.5, 0.5)), L, B, i;
  if (s * s == n)
    return s;
  for (int k = 0; k < 16 && n <= (LL)((long double)(LLONG / mp[k])); k++) {
    D = mp[k] * n;
    Po = Prev = P = (LL)pow(D, 0.5);
    Qrev = 1;
    Q = D - Po * Po;
    L = 2 * (LL)pow(2 * s, 0.5);
    B = 3 * L;
    for (i = 2; i < B; i++) {
      b = (LL)((Po + P) / Q);
      P = b * Q - P;
      q = Q;
      Q = Qrev + b * (Prev - P);
      r = (LL)(pow(Q, 0.5) + 0.5);
      if (!(i & 1) && r * r == Q)
        break;
      Qrev = q;
      Prev = P;
    };
    if (i >= B)
      continue;
    b = (LL)((Po - P) / r);
    Prev = P = b * r + P;
    Qrev = r;
    Q = (D - Prev * Prev) / Qrev;
    i = 0;
    do {
      b = (LL)((Po + P) / Q);
      Prev = P;
      P = b * Q - P;
      q = Q;
      Q = Qrev + b * (Prev - P);
      Qrev = q;
      i++;
    } while (P != Prev);
    r = GCD(n, Qrev);
    if (r != 1 && r != n)
      return r;
  }
  return 0;
}
int main(void) {
  LL a = 0, p = 1, q = -1, N = IN();
  if (N <= 1)
    return puts("0"), 0;
  Exp(N, 2);
  a = e[count[1]];
  N = count[0];
  Exp(N, 3);
  a += e[count[1]];
  N = count[0];
  while (q * q <= UnUseMethod) {
    p += 6, q += 6;
    Exp(N, p);
    a += e[count[1]];
    N = count[0];
    Exp(N, q);
    a += e[count[1]];
    N = count[0];
  }
  if (N <= UnUseMethod) {
    if (N > 1) {
      a++;
    }
    return printf("%lld\\n", a), 0;
  }
  if (MillerRabin(N)) {
    a++;
    return printf("%lld\\n", a), 0;
  }
  while (N >= UnUseMethod) {
    p = SQUFOF(N);
    while (p < q)
      p = SQUFOF(p);
    while (!MillerRabin(p))
      p = SQUFOF(p);
    Exp(N, p);
    a += e[count[1]];
    N = count[0];
  }
  if (MillerRabin(N)) {
    a++;
  }
  return printf("%lld\\n", a), 0;
}