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

#include <bits/stdc++.h>
#define int long long
#define lol long long

using namespace std;

// typedef long long lol;
const int N = 1e3 + 5;
int _w;

int A, B, X, Y, C;

void exgcd(int a, int b, lol &x, lol &y) {
  if (!b) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}

int inv(int a, int m) {
  lol x, y;
  exgcd(a, m, x, y);
  x = (x % m + m) % m;
  return x;
}

inline void solve(void) {
  _w = scanf("%lld%lld%lld%lld%lld", &A, &X, &B, &Y, &C);
  int g = __gcd(A, B);
  A /= g, B /= g, C /= __gcd(g, C);
  for (int _ = 0, t; _ < 2; ++_) {
    g = __gcd(A, C);
    A /= g, C /= g;
    t = __gcd(g, B);
    B /= t, Y /= g / t;
    swap(A, B), swap(X, Y);
  }
  if (C == 1) {
    printf("%lld\\n", X + Y);
    return;
  }
  int D = (lol)A * inv(B, C) % C, ID = inv(D, C);
  vector<int> x, y, n;
  int W = C, H = D;
  lol now = 0;
  while (W) {
    int d = W / H;
    x.push_back((now % C) * ID % C);
    if (now == 0)
      y.push_back(C);
    else
      y.push_back((C - now) % C);
    n.push_back(d);
    now += d * H;
    W %= H;
    if (!W)
      break;
    H %= W;
    if (!H)
      H = W;
  }
  x.push_back(C), y.push_back(0);
  int ans = 0;
  function<lol(lol, lol)> Div = [](lol a, lol b) {
    return a / b - (a % b && (a ^ b) < 0);
  };
  for (int i = 1, lx, ly, rx, ry, ct, l, r, mid, res, dx, dy;
       i < (int)(x.size()); ++i) {
    lx = x[i - 1], rx = x[i], ly = y[i - 1], ry = y[i], ct = n[i - 1];
    l = 0, r = X + Y + 1, res = -1, dx = (rx - lx) / ct, dy = (ly - ry) / ct;
    while (l <= r) {
      mid = (l + r) >> 1;
      lol p = Div(X - (lol)mid * lx, dx);
      lol q = Div(Y - (lol)mid * ry, dy);
      if (p >= 0 && q >= 0 && p + q >= (lol)ct * mid)
        res = mid, l = mid + 1;
      else
        r = mid - 1;
    }
    ans = max(ans, res);
  }
  printf("%lld\\n", ans);
}

signed main(void) {
  int T;
  _w = scanf("%lld", &T);
  while (T--)
    solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long lol;
const int N = 1e3 + 5;
int _w;

int A, B, X, Y, C;

void exgcd(int a, int b, lol &x, lol &y) {
  if (!b) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}

int inv(int a, int m) {
  lol x, y;
  exgcd(a, m, x, y);
  x = (x % m + m) % m;
  return x;
}

inline void solve(void) {
  _w = scanf("%d%d%d%d%d", &A, &X, &B, &Y, &C);
  int g = __gcd(A, B);
  A /= g, B /= g, C /= __gcd(g, C);
  for (int _ = 0, t; _ < 2; ++_) {
    g = __gcd(A, C);
    A /= g, C /= g;
    t = __gcd(g, B);
    B /= t, Y /= g / t;
    swap(A, B), swap(X, Y);
  }
  if (C == 1) {
    printf("%d\\n", X + Y);
    return;
  }
  int D = (lol)A * inv(B, C) % C, ID = inv(D, C);
  vector<int> x, y, n;
  int W = C, H = D;
  lol now = 0;
  while (W) {
    int d = W / H;
    x.push_back((now % C) * ID % C);
    if (now == 0)
      y.push_back(C);
    else
      y.push_back((C - now) % C);
    n.push_back(d);
    now += d * H;
    W %= H;
    if (!W)
      break;
    H %= W;
    if (!H)
      H = W;
  }
  x.push_back(C), y.push_back(0);
  int ans = 0;
  function<lol(lol, lol)> Div = [](lol a, lol b) {
    return a / b - (a % b && (a ^ b) < 0);
  };
  for (int i = 1, lx, ly, rx, ry, ct, l, r, mid, res, dx, dy; i < int(x.size());
       ++i) {
    lx = x[i - 1], rx = x[i], ly = y[i - 1], ry = y[i], ct = n[i - 1];
    l = 0, r = X + Y + 1, res = -1, dx = (rx - lx) / ct, dy = (ly - ry) / ct;
    while (l <= r) {
      mid = (l + r) >> 1;
      lol p = Div(X - (lol)mid * lx, dx);
      lol q = Div(Y - (lol)mid * ry, dy);
      if (p >= 0 && q >= 0 && p + q >= (lol)ct * mid)
        res = mid, l = mid + 1;
      else
        r = mid - 1;
    }
    ans = max(ans, res);
  }
  printf("%d\\n", ans);
}

int main(void) {
  int T;
  _w = scanf("%d", &T);
  while (T--)
    solve();
  return 0;
}