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

#include <bits/stdc++.h>
using namespace std;
/*
  l:??????
  r:??????
  h:?????¨????°´???
  w:1?§??????????????°´??????
  lkabe:???????£??????????
  rkabe:???????£??????????
*/
const double EPS = 1e-8;
struct dat {
  double l, r, h, w, lkabe, rkabe;
};
typedef pair<double, double> P;
typedef pair<P, int> PP;
vector<dat> A;

void Debug2() { cout << "l r h w lkabe rkabe" << endl; }
void Debug(dat a) {
  cout << a.l << " " << a.r << " " << a.h << "  " << a.w << " " << a.lkabe
       << " " << a.rkabe << endl;
}
void Debug() {
  for (int i = 0; i < (int)A.size(); i++)
    Debug(A[i]);
}

double getMinTime() {
  double res = 1e9;
  for (dat a : A) {
    if (a.w == 0)
      continue;
    double t = ((min(a.lkabe, a.rkabe) - a.h) * (a.r - a.l) * 30) / a.w;
    res = min(res, t);
  }
  return res;
}

dat Merge(dat l, dat r) {
  // assert(l.h == r.h);
  dat res;
  res.l = l.l;
  res.r = r.r;
  res.h = min(r.h, l.h);
  res.w = l.w + r.w;
  res.lkabe = l.lkabe;
  res.rkabe = r.rkabe;
  return res;
}

bool replace(int idx, int flg) {
  A[idx + flg].w += A[idx].w;
  A[idx].w = 0;
  if (abs(A[idx + flg].h - A[idx].h) > EPS)
    return 0;
  if (flg == 1)
    A[idx] = Merge(A[idx], A[idx + 1]);
  if (flg == -1)
    A[idx] = Merge(A[idx - 1], A[idx]);
  A.erase(A.begin() + idx + flg);
  return 1;
}

void adTime(double sec) {
  for (int i = 0; i < (int)A.size(); i++) {
    if (A[i].w == 0)
      continue;
    A[i].h += (sec * A[i].w) / (30 * (A[i].r - A[i].l));
  }

  int update = 1, cnt = 0;
  while (update) {
    update = 0;
    for (int i = 0; i < (int)A.size(); i++) {
      if (A[i].w == 0)
        continue;

      if (A[i].lkabe <= A[i].h + EPS) {
        update = 1, replace(i, -1);
        break;
      } else if (A[i].rkabe <= A[i].h + EPS) {
        update = 1, replace(i, 1);
        break;
      }
    }
  }
}

void sim(double t) {
  while (t) {
    double sec = min(t, getMinTime());
    assert(sec >= 0);
    adTime(sec);
    t -= sec;
  }
}

double getH(int x) {
  for (int i = 0; i < (int)A.size(); i++)
    if (A[i].l < x && x < A[i].r)
      return A[i].h;
  return -1;
}

int main() {
  int q;
  cin >> q;
  while (q--) {
    int n;
    cin >> n;
    A.resize(n + 1);
    double l = 0, r, lkabe = 1e15, rkabe;
    for (int i = 0; i < n; i++, l = r, lkabe = rkabe) {
      cin >> r >> rkabe;
      A[i] = (dat){l, r, 0, 0, lkabe, rkabe};
      if (i == n - 1)
        A[n] = (dat){r, 100, 0, 0, rkabe, 1e15};
    }

    int m;
    cin >> m;
    for (int i = 0, x, w; i < m; i++) {
      cin >> x >> w;
      for (dat &a : A)
        if (a.l < x && x < a.r)
          a.w += w;
    }
    int L;
    cin >> L;
    vector<PP> que(L);
    for (int i = 0; i < L; i++)
      cin >> que[i].first.second >> que[i].first.first, que[i].second = i;
    sort(que.begin(), que.end());

    vector<double> ans(L);
    int sec = 0;
    for (int i = 0; i < L; i++) {
      double x = que[i].first.second, t = que[i].first.first;
      int idx = que[i].second;
      sim(t - sec);
      ans[idx] = min(50.0, getH(x));
      sec = t;
    }

    for (int i = 0; i < L; i++)
      printf("%.8f\\n", ans[i]);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
/*
  l:??????
  r:??????
  h:?????¨????°´???
  w:1?§??????????????°´??????
  lkabe:???????£??????????
  rkabe:???????£??????????
*/
const double EPS = 1e-8;
struct dat {
  double l, r, h, w, lkabe, rkabe;
};
typedef pair<double, double> P;
typedef pair<P, int> PP;
vector<dat> A;

void Debug2() { cout << "l r h w lkabe rkabe" << endl; }
void Debug(dat a) {
  cout << a.l << " " << a.r << " " << a.h << "  " << a.w << " " << a.lkabe
       << " " << a.rkabe << endl;
}
void Debug() {
  for (int i = 0; i < (int)A.size(); i++)
    Debug(A[i]);
}

double getMinTime() {
  double res = 1e9;
  for (dat a : A) {
    if (a.w == 0)
      continue;
    double t = ((min(a.lkabe, a.rkabe) - a.h) * (a.r - a.l) * 30) / a.w;
    res = min(res, t);
  }
  return res;
}

dat Merge(dat l, dat r) {
  assert(l.h == r.h);
  dat res;
  res.l = l.l;
  res.r = r.r;
  res.h = min(r.h, l.h);
  res.w = l.w + r.w;
  res.lkabe = l.lkabe;
  res.rkabe = r.rkabe;
  return res;
}

bool replace(int idx, int flg) {
  A[idx + flg].w += A[idx].w;
  A[idx].w = 0;
  if (A[idx + flg].h != A[idx].h)
    return 0;
  if (flg == 1)
    A[idx] = Merge(A[idx], A[idx + 1]);
  if (flg == -1)
    A[idx] = Merge(A[idx - 1], A[idx]);
  A.erase(A.begin() + idx + flg);
  return 1;
}

void adTime(double sec) {
  for (int i = 0; i < (int)A.size(); i++) {
    if (A[i].w == 0)
      continue;
    A[i].h += (sec * A[i].w) / (30 * (A[i].r - A[i].l));
  }

  int update = 1;
  while (update) {
    update = 0;
    for (int i = 0; i < (int)A.size(); i++) {
      if (A[i].w == 0)
        continue;
      if (A[i].lkabe <= A[i].h + EPS) {
        update = 1, replace(i, -1);
        break;
      } else if (A[i].rkabe <= A[i].h + EPS) {
        update = 1, replace(i, 1);
        break;
      }
    }
  }
}

void sim(double t) {
  while (t) {
    double sec = min(t, getMinTime());
    assert(sec >= 0);
    adTime(sec);
    t -= sec;
  }
}

double getH(int x) {

  for (int i = 0; i < (int)A.size(); i++)
    if (A[i].l < x && x < A[i].r)
      return A[i].h;
  return -1;
}

int main() {
  int q;
  cin >> q;
  while (q--) {
    int n;
    cin >> n;
    A.resize(n + 1);
    double l = 0, r, lkabe = 1e15, rkabe;
    for (int i = 0; i < n; i++, l = r, lkabe = rkabe) {
      cin >> r >> rkabe;
      A[i] = (dat){l, r, 0, 0, lkabe, rkabe};
      if (i == n - 1)
        A[n] = (dat){r, 100, 0, 0, rkabe, 1e15};
    }

    int m;
    cin >> m;
    for (int i = 0, x, w; i < m; i++) {
      cin >> x >> w;
      for (dat &a : A)
        if (a.l < x && x < a.r)
          a.w += w;
    }
    int L;
    cin >> L;
    vector<PP> que(L);
    for (int i = 0; i < L; i++)
      cin >> que[i].first.second >> que[i].first.first, que[i].second = i;
    sort(que.begin(), que.end());

    vector<double> ans(L);
    int sec = 0;
    for (int i = 0; i < L; i++) {
      double x = que[i].first.second, t = que[i].first.first;
      int idx = que[i].second;
      sim(t - sec);
      ans[idx] = min(50.0, getH(x));
      sec = t;
    }

    for (int i = 0; i < L; i++)
      printf("%.8f\\n", ans[i]);
  }
  return 0;
}