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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

template <typename T> class SegTree {
public:
  SegTree(int n, function<T(T, T)> operation, function<T(T, T)> update,
          T identity = T()) {
    int ne = 1;
    while (ne < n) {
      ne *= 2;
    }
    this->n_ = n;
    this->ne_ = ne;

    this->data_ = vector<T>(this->ne_ * 2, identity);

    this->operation_ = operation;
    this->update_ = update;
    this->identity_ = identity;
  }

  const T &Val(int i) const { return this->data_[i + this->ne_ - 1]; }

  void Update(int i, const T &v) {
    int idx = i + this->ne_ - 1;
    this->data_[idx] = this->update_(this->data_[idx], v);

    while (idx != 0) {
      idx = (idx - 1) / 2;
      int lidx = idx * 2 + 1;
      int ridx = idx * 2 + 2;
      this->data_[idx] = this->operation_(this->data_[lidx], this->data_[ridx]);
    }
  }

  T QueryOpen(int l, int r) const {
    return this->QueryInternal(l, r, 0, this->ne_, 0);
  }

  T QueryClose(int l, int r) const { return QueryOpen(l, r + 1); }

private:
  T QueryInternal(int l, int r, int lc, int rc, int idx) const {
    if (l <= lc && rc <= r) {
      return this->data_[idx];
    }
    if (rc <= l || r <= lc) {
      return this->identity_;
    }

    int m = (lc + rc) / 2;

    int lidx = idx * 2 + 1;
    int ridx = idx * 2 + 2;

    if (r <= m) {
      return this->QueryInternal(l, r, lc, m, lidx);
    } else if (m <= l) {
      return this->QueryInternal(l, r, m, rc, ridx);
    } else {
      return this->operation_(this->QueryInternal(l, r, lc, m, lidx),
                              this->QueryInternal(l, r, m, rc, ridx));
    }
  }

  size_t n_;
  size_t ne_;
  vector<T> data_;
  function<T(T, T)> operation_;
  function<T(T, T)> update_;
  T identity_;
};

struct S {
  int i;
  int p;
  int v;
};

auto cmp = [](const S &lhs, const S &rhs) { return lhs.p < rhs.p; };

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  // cout << fixed << setprecision(20);

  int h, w;
  cin >> h >> w;

  set<S, decltype(cmp)> values(cmp);
  FOR_LE(i, 1, w) { values.insert({i, i, 0}); }
  auto process = [](int lhs, int rhs) { return min(lhs, rhs); };
  auto update = [](int lhs, int rhs) { return rhs; };
  SegTree<int> st(w + 1, process, update);
  st.Update(0, INT_MAX);

  FOR_LT(i, 0, h) {
    // cout << i << endl;
    int a, b;
    cin >> a >> b;
    auto bit = values.lower_bound({0, a, 0});
    auto eit = values.upper_bound({0, b + 1, 0});
    // cout << a << " " << b << endl;
    // cout << "bit " << bit->i << endl;
    if (bit != eit) {
      auto fit = eit;
      fit--;
      S s = *fit;
      s.v += (b + 1 - s.p);
      s.p = b + 1;
      if (w < s.p) {
        st.Update(s.i, INT_MAX);
      } else {
        // cout << "update : " << s.i << " " << s.v << endl;
        st.Update(s.i, s.v);
      }
      while (bit != eit) {
        // cout << "erase : " << bit->i << endl;
        if (bit->i != s.i) {
          st.Update(bit->i, INT_MAX);
        }
        bit = values.erase(bit);
      }
      values.insert(s);
      // cout << "valuse" << endl;
      // for (auto& v : values) {
      // cout << v.i << " " << v.p << " " << v.v << endl;
      //}
    }

    int ans = st.QueryClose(1, w);
    if (ans == INT_MAX) {
      cout << -1 << endl;
    } else {
      cout << ans + (i + 1) << endl;
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

template <typename T> class SegTree {
public:
  SegTree(int n, function<T(T, T)> operation, function<T(T, T)> update,
          T identity = T()) {
    int ne = 1;
    while (ne < n) {
      ne *= 2;
    }
    this->n_ = n;
    this->ne_ = ne;

    this->data_ = vector<T>(this->ne_ * 2, identity);

    this->operation_ = operation;
    this->update_ = update;
    this->identity_ = identity;
  }

  const T &Val(int i) const { return this->data_[i + this->ne_ - 1]; }

  void Update(int i, const T &v) {
    int idx = i + this->ne_ - 1;
    this->data_[idx] = this->update_(this->data_[idx], v);

    while (idx != 0) {
      idx = (idx - 1) / 2;
      int lidx = idx * 2 + 1;
      int ridx = idx * 2 + 2;
      this->data_[idx] = this->operation_(this->data_[lidx], this->data_[ridx]);
    }
  }

  T QueryOpen(int l, int r) const {
    return this->QueryInternal(l, r, 0, this->ne_, 0);
  }

  T QueryClose(int l, int r) const { return QueryOpen(l, r + 1); }

private:
  T QueryInternal(int l, int r, int lc, int rc, int idx) const {
    if (l <= lc && rc <= r) {
      return this->data_[idx];
    }
    if (rc <= l || r <= lc) {
      return this->identity_;
    }

    int m = (lc + rc) / 2;

    int lidx = idx * 2 + 1;
    int ridx = idx * 2 + 2;

    if (r <= m) {
      return this->QueryInternal(l, r, lc, m, lidx);
    } else if (m <= l) {
      return this->QueryInternal(l, r, m, rc, ridx);
    } else {
      return this->operation_(this->QueryInternal(l, r, lc, m, lidx),
                              this->QueryInternal(l, r, m, rc, ridx));
    }
  }

  size_t n_;
  size_t ne_;
  vector<T> data_;
  function<T(T, T)> operation_;
  function<T(T, T)> update_;
  T identity_;
};

struct S {
  int i;
  int p;
  int v;
};

auto cmp = [](const S &lhs, const S &rhs) { return lhs.p < rhs.p; };

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  // cout << fixed << setprecision(20);

  int h, w;
  cin >> h >> w;

  set<S, decltype(cmp)> values(cmp);
  FOR_LE(i, 1, w) { values.insert({i, i, 0}); }
  auto process = [](int lhs, int rhs) { return min(lhs, rhs); };
  auto update = [](int lhs, int rhs) { return rhs; };
  SegTree<int> st(w + 1, process, update);
  st.Update(0, INT_MAX);

  FOR_LT(i, 0, h) {
    // cout << i << endl;
    int a, b;
    cin >> a >> b;
    auto bit = values.lower_bound({0, a, 0});
    auto eit = values.upper_bound({0, b + 1, 0});
    // cout << a << " " << b << endl;
    // cout << "bit " << bit->i << endl;
    if (bit != eit) {
      auto fit = eit;
      fit--;
      S s = *fit;
      s.v += (b + 1 - s.p);
      s.p = b + 1;
      if (w < s.p) {
        st.Update(s.i, INT_MAX);
      } else {
        // cout << "update : " << s.i << " " << s.v << endl;
        st.Update(s.i, s.v);
      }
      while (bit != eit) {
        // cout << "erase : " << bit->i << endl;
        if (bit->i != s.i) {
          st.Update(bit->i, INT_MAX);
        }
        bit = values.erase(bit);
      }
      values.insert(s);
      // cout << "valuse" << endl;
      for (auto &v : values) {
        // cout << v.i << " " << v.p << " " << v.v << endl;
      }
    }

    int ans = st.QueryClose(1, w);
    if (ans == INT_MAX) {
      cout << -1 << endl;
    } else {
      cout << ans + (i + 1) << endl;
    }
  }

  return 0;
}