Problem p02656 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int T, A, X, B, Y, C, ans;

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

void exgcd(int a, int b, int &x, int &y) {
  if (!b) {
    x = 1, y = 0;
    return;
  }
  // ax + by = gcd(a,b)
  // bx + (a-b[a/b])y = gcd(a,b)
  // ya + (x-[a/b]y)b = gcd(a,b)
  int x_ = 0, y_ = 0;
  exgcd(b, a % b, x_, y_);
  x = y_, y = x_ - (a / b) * y_;
}

int inverse(int a, int mod) {
  int x = 0, y = 0;
  // ax - mod k = 1
  exgcd(a, mod, x, y);
  return (x % mod + mod) % mod;
}

int solve(int k, int p, int l, int r) {
  if (r >= l + p)
    r = l + p - 1;
  if (r >= p) {
    int x = (l + k - 1) / k;
    int res = solve(k, p, l - k * x, r - k * x);
    if (res == -1)
      return -1;
    return x + res;
  }
  k %= p;
  if (l <= -p) {
    int x = ((-p - l) / p) + 1;
    l += p * x, r += p * x;
  }
  if (!k) {
    if (l <= 0 && r >= 0)
      return 0;
    else
      return -1;
  }
  int q = solve(p, k, -r, -l);
  if (q == -1)
    return -1;
  // ki >= l + qp
  int ret = max(0ll, (l + 1LL * q * p + k - 1) / k);
  if (k * ret > r + 1LL * q * p) {
    puts("???");
  }
  return ret;
}

int solve(int k, int p, int l, int r, int a) {
  int v = 1LL * k * a % p;
  l -= v, r -= v;
  return solve(k, p, l, r) + a;
}

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d%d%d%d%d", &A, &X, &B, &Y, &C);
    int d = gcd(gcd(A, B), C);
    A /= d, B /= d, C /= d;
    int dA = gcd(A, C), dB = gcd(B, C);
    X /= dB, Y /= dA, C /= (dA * dB);
    A /= dA, B /= dB;
    ans = 0;
    A %= C, B %= C;
    if (!A || !B) {
      if (!A && !B) {
        printf("%d\\n", X + Y);
      } else if (!A) {
        printf("%d\\n", X + Y / C);
      } else {
        printf("%d\\n", X / C + Y);
      }
      continue;
    }
    int k = 1LL * inverse(B, C) * A % C;
    int cur_x = 0, cur_y = C;
    while (cur_x != C) {
      int nxt_x = solve(C - k, C, 0, cur_y - 1, cur_x + 1);
      int nxt_y = 1LL * (C - k) * nxt_x % C;
      int delta_x = nxt_x - cur_x, delta_y = cur_y - nxt_y;
      int c = cur_y / delta_y;
      nxt_x = cur_x + delta_x * c;
      nxt_y = cur_y - delta_y * c;
      int L = 0,
          R = min(cur_x ? (X / cur_x) : 0x3f3f3f3f,
                  nxt_y ? (Y / nxt_y) : (0x3f3f3f3f)),
          res = 0;
      while (L <= R) {
        int mid = (L + R) >> 1;
        ll lb = max(0LL, (1LL * mid * cur_y - Y + delta_y - 1) / delta_y),
           rb = min(1LL * mid * c, (X - 1LL * mid * cur_x) / delta_x);
        if (lb <= rb) {
          res = mid;
          L = mid + 1;
        } else
          R = mid - 1;
      }
      ans = max(ans, res);
      cur_x = nxt_x, cur_y = nxt_y;
    }
    printf("%d\\n", ans);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int T, A, X, B, Y, C, ans;

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

void exgcd(int a, int b, int &x, int &y) {
  if (!b) {
    x = 1, y = 0;
    return;
  }
  // ax + by = gcd(a,b)
  // bx + (a-b[a/b])y = gcd(a,b)
  // ya + (x-[a/b]y)b = gcd(a,b)
  int x_ = 0, y_ = 0;
  exgcd(b, a % b, x_, y_);
  x = y_, y = x_ - (a / b) * y_;
}

int inverse(int a, int mod) {
  int x = 0, y = 0;
  // ax - mod k = 1
  exgcd(a, mod, x, y);
  return (x % mod + mod) % mod;
}

int solve(int k, int p, int l, int r) {
  if (r >= l + p)
    r = l + p - 1;
  if (r >= p) {
    int x = (l + k - 1) / k;
    int res = solve(k, p, l - k * x, r - k * x);
    if (res == -1)
      return -1;
    return x + res;
  }
  k %= p;
  if (l <= -p) {
    int x = ((-p - l) / p) + 1;
    l += p * x, r += p * x;
  }
  if (!k) {
    if (l <= 0 && r >= 0)
      return 0;
    else
      return -1;
  }
  int q = solve(p, k, -r, -l);
  if (q == -1)
    return -1;
  // ki >= l + qp
  return max(0, (l + q * p + k - 1) / k);
}

int solve(int k, int p, int l, int r, int a) {
  l -= k * a, r -= k * a;
  return solve(k, p, l, r) + a;
}

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d%d%d%d%d", &A, &X, &B, &Y, &C);
    int d = gcd(gcd(A, B), C);
    A /= d, B /= d, C /= d;
    int dA = gcd(A, C), dB = gcd(B, C);
    X /= dB, Y /= dA, C /= (dA * dB);
    A /= dA, B /= dB;
    ans = 0;
    A %= C, B %= C;
    if (!A || !B) {
      if (!A && !B) {
        printf("%d\\n", X + Y);
      } else if (!A) {
        printf("%d\\n", X + Y / C);
      } else {
        printf("%d\\n", X / C + Y);
      }
      continue;
    }
    int k = 1LL * inverse(B, C) * A % C;
    int cur_x = 0, cur_y = C;
    while (cur_x != C) {
      int nxt_x = solve(C - k, C, 0, cur_y - 1, cur_x + 1);
      int nxt_y = 1LL * (C - k) * nxt_x % C;
      int delta_x = nxt_x - cur_x, delta_y = cur_y - nxt_y;
      int c = cur_y / delta_y;
      nxt_x = cur_x + delta_x * c;
      nxt_y = cur_y - delta_y * c;
      int L = 0,
          R = min(cur_x ? (X / cur_x) : 0x3f3f3f3f,
                  nxt_y ? (Y / nxt_y) : (0x3f3f3f3f)),
          res = 0;
      while (L <= R) {
        int mid = (L + R) >> 1;
        ll lb = max(0LL, (1LL * mid * cur_y - Y + delta_y - 1) / delta_y),
           rb = min(1LL * mid * c, (X - 1LL * mid * cur_x) / delta_x);
        if (lb <= rb) {
          res = mid;
          L = mid + 1;
        } else
          R = mid - 1;
      }
      ans = max(ans, res);
      cur_x = nxt_x, cur_y = nxt_y;
    }
    printf("%d\\n", ans);
  }
  return 0;
}