Problem p03710 (C++)

Buggy submission (status: Time Limit Exceeded):
/********************************************************************************

        Code by a weak man who named CYJian, and he hopes the code can get more
 scores.

        Algorithm:

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge                                                                     \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin),               \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s ".in", "r", stdin), freopen(s ".out", "w", stdout)

template <typename T> inline void read(T &x) {
  char ch, t = 0;
  x = 0;
  while (!isdigit(ch = ge))
    t |= ch == '-';
  while (isdigit(ch))
    x = x * 10 + (ch ^ 48), ch = ge;
  x = t ? -x : x;
}
inline int read_int() {
  int x;
  return read(x), x;
}
inline ll read_ll() {
  ll x;
  return read(x), x;
}

template <typename T> inline void chkmin(T &a, T b) { a = a < b ? a : b; }

const ll lim = 2e18;
const int mod = 1e9 + 7;

ll fib[1000];
int mx[810][810];
int val[810][810];

inline int dfs(ll x, ll y, int d, ll Lx, ll Ly, int &ans) {
  if (x * fib[d - 1] + y * (d > 1 ? fib[d - 2] : 0) > Lx)
    return 0;
  if (x * fib[d] + y * fib[d - 1] > Ly)
    return 0;
  if (d == 1) {
    if (Lx >= x + y)
      ans = (ans + (Lx - y) / x) % mod;
    return ans = (ans + (Ly - y) / x) % mod, 1;
  }
  for (int i = 1 + (!y);; ++i)
    if (!dfs(y + x * i, x, d - 1, Lx, Ly, ans))
      return i > 1;
}

int main() {
#ifndef ONLINE_JUDGE
  FILE("fibo");
#endif
  fib[0] = 1, fib[1] = 1;
  int N = 1;
  while (fib[N] <= lim)
    ++N, fib[N] = fib[N - 1] + fib[N - 2];
  int q = ri;
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++) {
      if (i > j)
        mx[i][j] = mx[j][i];
      else
        mx[i][j] = mx[j % i][i] + 1;
      val[i][j] = 1;
    }
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++)
      if (mx[i][j] == mx[i][j - 1])
        val[i][j] += val[i][j - 1];
      else if (mx[i][j] < mx[i][j - 1])
        mx[i][j] = mx[i][j - 1], val[i][j] = val[i][j - 1];
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++)
      if (mx[i][j] == mx[i - 1][j])
        val[i][j] += val[i - 1][j];
      else if (mx[i][j] < mx[i - 1][j])
        mx[i][j] = mx[i - 1][j], val[i][j] = val[i - 1][j];
  while (q--) {
    ll x = rl, y = rl;
    if (x > y)
      swap(x, y);
    int idx = upper_bound(fib + 1, fib + 1 + N, x) - fib - 1;
    int idy = upper_bound(fib + 1, fib + 1 + N, y) - fib - 1;
    if (y <= 800)
      printf("%d %d\n", mx[x][y], val[x][y]);
    else {
      if (x == 1) {
        printf("1 %d\n", y % mod);
      } else {
        int mx = min(idy - 1, idx), ans = 0;
        printf("%d %d\n", mx, (dfs(1, 0, mx, x, y, ans), ans));
      }
    }
  }
  return 0;
}

Fixed submission:
/********************************************************************************

        Code by a weak man who named CYJian, and he hopes the code can get more
 scores.

        Algorithm:

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge                                                                     \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin),               \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s ".in", "r", stdin), freopen(s ".out", "w", stdout)

template <typename T> inline void read(T &x) {
  char ch, t = 0;
  x = 0;
  while (!isdigit(ch = ge))
    t |= ch == '-';
  while (isdigit(ch))
    x = x * 10 + (ch ^ 48), ch = ge;
  x = t ? -x : x;
}
inline int read_int() {
  int x;
  return read(x), x;
}
inline ll read_ll() {
  ll x;
  return read(x), x;
}

template <typename T> inline void chkmin(T &a, T b) { a = a < b ? a : b; }

const ll lim = 2e18;
const int mod = 1e9 + 7;

ll fib[1000];
int mx[810][810];
int val[810][810];

inline int dfs(ll x, ll y, int d, ll Lx, ll Ly, int &ans) {
  if (x * fib[d - 1] + y * (d > 1 ? fib[d - 2] : 0) > Lx)
    return 0;
  if (x * fib[d] + y * fib[d - 1] > Ly)
    return 0;
  if (d == 1) {
    if (Lx >= x + y)
      ans = (ans + (Lx - y) / x) % mod;
    return ans = (ans + (Ly - y) / x) % mod, 1;
  }
  for (int i = 1 + (!y);; ++i)
    if (!dfs(y + x * i, x, d - 1, Lx, Ly, ans))
      return i > 1;
}

int main() {
  fib[0] = 1, fib[1] = 1;
  int N = 1;
  while (fib[N] <= lim)
    ++N, fib[N] = fib[N - 1] + fib[N - 2];
  int q = ri;
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++) {
      if (i > j)
        mx[i][j] = mx[j][i];
      else
        mx[i][j] = mx[j % i][i] + 1;
      val[i][j] = 1;
    }
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++)
      if (mx[i][j] == mx[i][j - 1])
        val[i][j] += val[i][j - 1];
      else if (mx[i][j] < mx[i][j - 1])
        mx[i][j] = mx[i][j - 1], val[i][j] = val[i][j - 1];
  for (int i = 1; i <= 800; i++)
    for (int j = 1; j <= 800; j++)
      if (mx[i][j] == mx[i - 1][j])
        val[i][j] += val[i - 1][j];
      else if (mx[i][j] < mx[i - 1][j])
        mx[i][j] = mx[i - 1][j], val[i][j] = val[i - 1][j];
  while (q--) {
    ll x = rl, y = rl;
    if (x > y)
      swap(x, y);
    int idx = upper_bound(fib + 1, fib + 1 + N, x) - fib - 1;
    int idy = upper_bound(fib + 1, fib + 1 + N, y) - fib - 1;
    if (y <= 800)
      printf("%d %d\n", mx[x][y], val[x][y]);
    else {
      if (x == 1) {
        printf("1 %d\n", y % mod);
      } else {
        int mx = min(idy - 1, idx), ans = 0;
        printf("%d %d\n", mx, (dfs(1, 0, mx, x, y, ans), ans));
      }
    }
  }
  return 0;
}