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

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <string>

#define rep2(i, b, n) for (int i = b; i < n; ++i)
#define repm(i, b, n) for (int i = b; i > n; --i)
#define rep(i, n) rep2(i, 0, n)
#define sz(v) v.size()
#define mk(x, y) make_pair(x, y)
#define fst first
#define scd second
#define MEMSET(x, n) memset(x, n, sizeof(x))
#define MEMZERO(x) MEMSET(x, 0)
#define URU(y) (!(y % 4) && y % 100 || !(y % 400))

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct Line {
  double l;
  double r;
  int num;
};

enum Check {
  LOW = 0,
  MID,
  HIGH,
};

double cross_product(float x1, float y1, float x2, float y2) {
  return ((x1 * y2) - (x2 * y1));
}

inline Check inRange(Line l, Line h, double x, double y, double w) {
  double v1, v2;

  v1 = cross_product(w, (l.r - l.l), x, (y - l.l));
  v2 = cross_product(w, (h.r - h.l), x, (y - h.l));

  if (0 < v1 && 0 < v2)
    return HIGH;
  if (0 > v1 && 0 > v2)
    return LOW;
  else
    return MID;
}

int main(void) {
  int n, m, w, h, S;
  Line T[30010];
  int N1[30010], S1[30010];

  while (cin >> n >> m >> w >> h >> S, n | m | w | h | S) {
    MEMZERO(T);

    rep2(i, 1, (m + 1)) { cin >> T[i].l >> T[i].r; }

    rep(i, n) {
      double x, y;
      cin >> x >> y;

      int low = 1, high = m;
      while (low <= high) {
        int mid = (low + high) / 2;
        Check c = inRange(T[mid - 1], T[mid], x, y, (double)w);

        if (c == LOW)
          high = mid;
        else if (c == HIGH)
          low = mid + 1;
        else // c == Check::MID
        {
          // cout << mid << endl;
          ++T[mid].num;
          break;
        }
      }
      /*
                              rep2 (j, 1, (m + 1))
                              {
                                      if (inRange(T[j-1], T[j], x, y,
         (double)w))
                                      {
                                              ++T[j].num;
                                              break;
                                      }
                              }
      */
    }

    int ans = n, sum = 0;

    rep(i, (m + 1)) {
      sum += T[i].num;
      N1[i] = sum;
      if (ans <= sum)
        break;
      if ((S * 2) <= (S1[i] = ((T[i].l + T[i].r) * w))) {
        ans = sum;
        break;
      }
    }
    // cout << ans << endl;
    /*
                    sum = 0;
                    repm (i, m, 0)
                    {
                            sum += T[i].num;
                            N2[i] = sum;
                            if (ans <= sum)
                                    break;
                            if((S * 2) <= (S2[i] = ((2 * h - (T[i-1].l +
       T[i-1].r)) * w)))
                            {
                                    ans = sum;
                                    break;
                            }
                    }
    */
    // cout << ans << endl;

    sum = 0;
    rep2(i, 0, m) {
      if (ans <= N1[i])
        break;
      int sub_sum = 0;
      repm(j, m, (i + 1)) {
        sub_sum += T[j].num;
        if (ans <= (N1[i] + sub_sum))
          break;
        if ((S * 2) <= (((2 * h - (T[j - 1].l + T[j - 1].r)) * w) + S1[i])) {
          ans = N1[i] + sub_sum;
          break;
        }
      }
    }

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

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <string>

#define rep2(i, b, n) for (int i = b; i < n; ++i)
#define repm(i, b, n) for (int i = b; i > n; --i)
#define rep(i, n) rep2(i, 0, n)
#define sz(v) v.size()
#define mk(x, y) make_pair(x, y)
#define fst first
#define scd second
#define MEMSET(x, n) memset(x, n, sizeof(x))
#define MEMZERO(x) MEMSET(x, 0)
#define URU(y) (!(y % 4) && y % 100 || !(y % 400))

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct Line {
  double l;
  double r;
  int num;
};

double cross_product(float x1, float y1, float x2, float y2) {
  return ((x1 * y2) - (x2 * y1));
}

bool inRange(Line l, Line h, double x, double y, double w) {
  double v1, v2;

  v1 = cross_product(w, (l.r - l.l), x, (y - l.l));
  v2 = cross_product(w, (h.r - h.l), x, (y - h.l));

  if ((0 < v1 && 0 < v2) || (0 > v1 && 0 > v2))
    return false;
  else
    return true;
}

int main(void) {
  int n, m, w, h, S;
  Line T[30010];
  int N1[30010], N2[30010];
  int S1[30010], S2[30010];

  while (cin >> n >> m >> w >> h >> S, n | m | w | h | S) {
    MEMZERO(T);
    MEMZERO(S1);
    MEMZERO(S2);

    rep2(i, 1, (m + 1)) { cin >> T[i].l >> T[i].r; }

    rep(i, n) {
      double x, y;
      cin >> x >> y;

      rep2(j, 1, (m + 1)) {
        if (inRange(T[j - 1], T[j], x, y, (double)w)) {
          ++T[j].num;
          break;
        }
      }
    }

    int ans = n, sum = 0;

    rep(i, (m + 1)) {
      sum += T[i].num;
      N1[i] = sum;
      if (ans <= sum)
        break;
      if ((S * 2) <= (S1[i] = ((T[i].l + T[i].r) * w))) {
        ans = sum;
        break;
      }
    }
    // cout << ans << endl;
    /*
                    sum = 0;
                    repm (i, m, 0)
                    {
                            sum += T[i].num;
                            N2[i] = sum;
                            if (ans <= sum)
                                    break;
                            if((S * 2) <= (S2[i] = ((2 * h - (T[i-1].l +
       T[i-1].r)) * w)))
                            {
                                    ans = sum;
                                    break;
                            }
                    }
    */
    // cout << ans << endl;

    sum = 0;
    rep2(i, 0, m) {
      if (ans <= N1[i])
        break;
      int sub_sum = 0;
      repm(j, m, (i + 1)) {
        sub_sum += T[j].num;
        if (ans <= (N1[i] + sub_sum))
          break;
        if ((S * 2) <= (((2 * h - (T[j - 1].l + T[j - 1].r)) * w) + S1[i])) {
          ans = N1[i] + sub_sum;
          break;
        }
      }
    }

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