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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
using ll = __int128_t;
using Int = long long int;

const ll INF = 1LL << 60;
Int W, H, V, T, x, y, p, q;

ll find_upper(ll X, ll cy, ll ty, ll piv) {
  ll ub = T * V, lb = piv - 1;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    ll Y = cy * mid + ty;

    ll dx = X - x, dy = Y - y;
    if (dx * dx + dy * dy > T * T * V * V) {
      ub = mid;
    } else {
      lb = mid;
    }
  }
  return ub;
}

ll find_lower(ll X, ll cy, ll ty, ll piv) {
  ll ub = piv, lb = -T * V;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    ll Y = cy * mid + ty;

    ll dx = X - x, dy = Y - y;
    if (dx * dx + dy * dy <= T * T * V * V) {
      ub = mid;
    } else {
      lb = mid;
    }
  }
  return ub;
}

bool is_valid(ll X, ll cy, ll ty, ll k) {
  ll Y = cy * k + ty;
  ll dx = X - x, dy = Y - y;
  return dx * dx + dy * dy <= T * T * V * V;
}

Int solve(ll cx, ll tx, ll cy, ll ty) {
  Int ret = 0;
  for (ll k = -T * V; k <= T * V; k++) {
    ll X = cx * k + tx, dx = X - x;
    if (dx * dx > T * T * V * V)
      continue;

    ll piv = INF;
    for (int k = -2; k <= 2; k++) {
      if (is_valid(X, cy, ty, k)) {
        piv = k;
        break;
      }
    }
    if (piv == INF)
      continue;
    ll ub = find_upper(X, cy, ty, piv);
    ll lb = find_lower(X, cy, ty, piv);
    ret += ub - lb;
  }
  return ret;
}

int main() {
  cin >> W >> H >> V >> T >> x >> y >> p >> q;

  Int ans = 0;
  ans += solve(2 * W, p, 2 * H, q);
  ans += solve(2 * W, p, 2 * H, 2 * H - q);
  ans += solve(2 * W, 2 * W - p, 2 * H, q);
  ans += solve(2 * W, 2 * W - p, 2 * H, 2 * H - q);

  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long int;

ll W, H, V, T, x, y, p, q;

ll find_upper(ll X, ll cy, ll ty) {
  ll ub = 10 * T * V, lb = -1;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    ll Y = cy * mid + ty;

    ll dx = X - x, dy = Y - y;
    // printf("mid = %lld, dx = %lld, dy = %lld, lim = %lld\\n", mid, dx, dy,
    // T*T*V*V);
    if (dx * dx + dy * dy > T * T * V * V) {
      ub = mid;
    } else {
      lb = mid;
    }
  }
  return ub;
}

ll find_lower(ll X, ll cy, ll ty) {
  ll ub = 0, lb = -10 * T * V;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    ll Y = cy * mid + ty;

    ll dx = X - x, dy = Y - y;
    if (dx * dx + dy * dy <= T * T * V * V) {
      ub = mid;
    } else {
      lb = mid;
    }
  }
  return ub;
}

ll solve(ll cx, ll tx, ll cy, ll ty) {
  ll ret = 0;
  for (ll k = -10 * T * V; k <= 10 * T * V; k++) {
    ll X = cx * k + tx, dx = X - x;
    if (dx * dx > T * T * V * V)
      continue;
    ll ub = find_upper(X, cy, ty);
    ll lb = find_lower(X, cy, ty);
    ret += ub - lb;
    // printf("X = %lld, ub = %lld, lb = %lld\\n", X, ub, lb);
  }
  // printf("ret = %lld\\n", ret);
  return ret;
}

int main() {
  cin >> W >> H >> V >> T >> x >> y >> p >> q;

  ll ans = 0;
  ans += solve(2 * W, p, 2 * H, q);
  ans += solve(2 * W, p, 2 * H, 2 * H - q);
  ans += solve(2 * W, 2 * W - p, 2 * H, q);
  ans += solve(2 * W, 2 * W - p, 2 * H, 2 * H - q);

  cout << ans << endl;
  return 0;
}