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

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

struct node {
  LL t, k, i;
  node(LL t = 0, LL k = 0, LL i = 0) : t(t), k(k), i(i) {}
  LL calc(LL x) { return t + k * x; }
};
vector<node> f;

LL gcd(LL x, LL y) { return y == 0 ? x : gcd(y, x % y); }

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

void calc(LL n, LL m, LL p, LL q, LL now) {
  if (!n || !m) {
    return;
  }
  if (n <= m) {
    LL t = (m - 1) / n;
    f.push_back(node(now + p, n + q, t));
    calc(n, m % n, p + (q + n) * t, q, now);
  } else {
    LL t = n / m;
    calc(n % m, m, p, q + (p + m) * t, now);
  }
}

LL up(LL x, LL y) { return (x + y - 1) / y; }

LL down(LL x, LL y) { return x / y; }

bool pd(LL u1, LL v1, LL u2, LL v2) { return u1 * v2 >= u2 * v1; }

LL calc(LL u1, LL v1, LL u2, LL v2, LL u, LL v) {
  LL ret = 0, l = 0, r = u + v;
  while (l <= r) {
    LL mid = (l + r) >> 1, t1 = 0, t2 = mid;
    if (u2 * mid - u >= 0) {
      t1 = max(t1, up(u2 * mid - u, u2 - u1));
    }
    if (v - v2 * mid < 0) {
      t2 = -1;
    } else {
      t2 = min(t2, down(v - v2 * mid, v1 - v2));
    }
    if (t1 <= t2) {
      ret = mid;
      l = mid + 1;
    } else
      r = mid - 1;
  }
  return ret;
}

void solve() {
  LL a, b, c, x, y;
  scanf("%lld%lld%lld%lld%lld", &a, &x, &b, &y, &c);
  LL g = gcd(a, b);
  a /= g;
  b /= g;
  c /= gcd(c, g);
  g = gcd(a, c);
  a /= g;
  c /= g;
  y /= g;
  g = gcd(b, c);
  b /= g;
  c /= g;
  x /= g;
  a %= c;
  b %= c;
  if (c == 1) {
    printf("%lld\\n", x + y);
    return;
  }
  LL x0 = 0, y0 = 0;
  exgcd(b, c, x0, y0);
  a = (a * x0 % c + c) % c;
  f.clear();
  f.push_back(node(0, 0, 1));
  calc(a, c, 0, 0, 0);
  f.push_back(node(c * a, 0, 1));
  LL ans = 0;
  for (size_t i = 0; i < f.size(); ++i) {
    if (f[i].i >= 2) {
      LL u1 = f[i].calc(1) / a, v1 = c - (a * u1) % c;
      LL u2 = f[i].calc(f[i].i) / a, v2 = c - (a * u2) % c;
      if (pd(v1, u1, y, x) && pd(y, x, v2, u2)) {
        LL l = 1, r = f[i].i - 1;
        while (l <= r) {
          LL mid = (l + r) >> 1;
          LL u1 = f[i].calc(mid) / a, v1 = c - (a * u1) % c;
          LL u2 = f[i].calc(mid + 1) / a, v2 = c - (a * u2) % c;
          if (!pd(v1, u1, y, x)) {
            r = mid - 1;
            continue;
          }
          if (!pd(y, x, v2, u2)) {
            l = mid + 1;
            continue;
          }
          ans = calc(u1, v1, u2, v2, x, y);
          break;
        }
        break;
      }
    }
    if (i + 1 < f.size()) {
      LL u1 = f[i].calc(f[i].i) / a, v1 = c - (a * u1) % c;
      LL u2 = f[i + 1].calc(1) / a, v2 = (c - (a * u2) % c) % c;
      if (pd(v1, u1, y, x) && pd(y, x, v2, u2)) {
        ans = calc(u1, v1, u2, v2, x, y);
        break;
      }
    }
  }
  printf("%lld\\n", ans);
}

int main() {
  LL T;
  scanf("%lld", &T);
  while (T--)
    solve();

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

struct node {
  LL t, k, i;
  node(LL t = 0, LL k = 0, LL i = 0) : t(t), k(k), i(i) {}
  LL calc(LL x) { return t + k * x; }
};
vector<node> f;

LL gcd(LL x, LL y) { return y == 0 ? x : gcd(y, x % y); }

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

void calc(LL n, LL m, LL p, LL now) {
  if (!n || !m) {
    return;
  }
  if (n <= m) {
    LL t = (m - 1) / n;
    f.push_back(node(now, n + p, t));
    calc(n, m % n, (n + p) * t, now + p);
  } else {
    LL t = n / m;
    calc(n % m, m, (m + p) * t, now + p);
  }
}

LL up(LL x, LL y) { return (x + y - 1) / y; }

LL down(LL x, LL y) { return x / y; }

bool pd(LL u1, LL v1, LL u2, LL v2) { return u1 * v2 >= u2 * v1; }

LL calc(LL u1, LL v1, LL u2, LL v2, LL u, LL v) {
  LL ret = 0, l = 0, r = u + v;
  while (l <= r) {
    LL mid = (l + r) >> 1, t1 = 0, t2 = mid;
    if (u2 * mid - u >= 0) {
      t1 = max(t1, up(u2 * mid - u, u2 - u1));
    }
    if (v - v2 * mid < 0) {
      t2 = -1;
    } else {
      t2 = min(t2, down(v - v2 * mid, v1 - v2));
    }
    if (t1 <= t2) {
      ret = mid;
      l = mid + 1;
    } else
      r = mid - 1;
  }
  return ret;
}

void solve() {
  LL a, b, c, x, y;
  scanf("%lld%lld%lld%lld%lld", &a, &x, &b, &y, &c);
  LL g = gcd(a, b);
  a /= g;
  b /= g;
  c /= gcd(c, g);
  g = gcd(a, c);
  a /= g;
  c /= g;
  y /= g;
  g = gcd(b, c);
  b /= g;
  c /= g;
  x /= g;
  a %= c;
  b %= c;
  LL x0 = 0, y0 = 0;
  exgcd(b, c, x0, y0);
  a = (a * x0 % c + c) % c;
  for (LL i = a, mx = 0; i <= 10000; i += a) {
    if (i % c > mx) {
      mx = i % c;
    }
  }
  f.push_back(node(0, 0, 1));
  calc(a, c, 0, 0);
  f.push_back(node(c * a, 0, 1));
  LL ans = 0;
  for (size_t i = 0; i < f.size(); ++i) {
    if (f[i].i >= 2) {
      LL u1 = f[i].calc(1) / a, v1 = c - (a * u1) % c;
      LL u2 = f[i].calc(f[i].i) / a, v2 = c - (a * u2) % c;
      if (pd(v1, u1, y, x) && pd(y, x, v2, u2)) {
        LL l = 1, r = f[i].i - 1;
        while (l <= r) {
          LL mid = (l + r) >> 1;
          LL u1 = f[i].calc(mid) / a, v1 = c - (a * u1) % c;
          LL u2 = f[i].calc(mid + 1) / a, v2 = c - (a * u2) % c;
          if (!pd(v1, u1, y, x)) {
            r = mid - 1;
            continue;
          }
          if (!pd(y, x, v2, u2)) {
            l = mid + 1;
            continue;
          }
          ans = calc(u1, v1, u2, v2, x, y);
          break;
        }
        break;
      }
    }
    if (i + 1 < f.size()) {
      LL u1 = f[i].calc(f[i].i) / a, v1 = c - (a * u1) % c;
      LL u2 = f[i + 1].calc(1) / a, v2 = c - (a * u2) % c;
      if (pd(v1, u1, y, x) && pd(y, x, v2, u2)) {
        ans = calc(u1, v1, u2, v2, x, y);
        break;
      }
    }
  }
  printf("%lld\\n", ans);
}

int main() {
  LL T;
  scanf("%lld", &T);
  while (T--)
    solve();

  return 0;
}