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

#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
template <class T = int> using V = vector<T>;
template <class T = int> using VV = V<V<T>>;
template <class T> void assign(V<T> &v, int n, const T &a = T()) {
  v.assign(n, a);
}
template <class T, class... Args>
void assign(V<T> &v, int n, const Args &...args) {
  v.resize(n);
  for (auto &&e : v)
    assign(e, args...);
}

struct P {
  int id, x, y;
};
auto comp_id = [](const P &lhs, const P &rhs) { return lhs.id < rhs.id; };
auto comp_x = [](const P &lhs, const P &rhs) { return lhs.x < rhs.x; };
auto comp_y = [](const P &lhs, const P &rhs) { return lhs.y < rhs.y; };

struct Monoid {
  using T = V<P>;
  static T op(const T &lhs, const T &rhs) {
    T res;
    merge(begin(lhs), end(lhs), begin(rhs), end(rhs), back_inserter(res),
          comp_y);
    return move(res);
  }
  template <class Itr> static T op(const T &lhs, Itr first, Itr last) {
    T res;
    merge(begin(lhs), end(lhs), first, last, back_inserter(res), comp_y);
    return move(res);
  }
  static T e() { return T(); }
};

template <class Monoid> struct SegmentTree {
  using T = typename Monoid::T;

  const int n;
  V<T> val;

  SegmentTree(int n) : n(n), val(2 * n, Monoid::e()) {}
  template <class Itr>
  SegmentTree(Itr first, Itr last)
      : n(distance(first, last)), val(2 * n, Monoid::e()) {
    copy(first, last, next(begin(val), n));
    build();
  }

  T &at(int i) { return val[i + n]; }

  void build() {
    for (int i = n - 1; i > 0; --i)
      val[i] = Monoid::op(val[2 * i], val[2 * i + 1]);
  }

  T get(int l, int r, int yl, int yr) const {
    T resl = Monoid::e(), resr = Monoid::e();
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) {
        resl = Monoid::op(
            resl, lower_bound(begin(val[l]), end(val[l]), P{-1, 0, yl}, comp_y),
            lower_bound(begin(val[l]), end(val[l]), P{-1, 0, yr}, comp_y));
        ++l;
      }
      if (r & 1) {
        --r;
        resr = Monoid::op(
            resr, lower_bound(begin(val[r]), end(val[r]), P{-1, 0, yl}, comp_y),
            lower_bound(begin(val[r]), end(val[r]), P{-1, 0, yr}, comp_y));
      }
    }
    return Monoid::op(resl, resr);
  }

  void set(int i, const T &a) {
    for (val[i += n] = a, i >>= 1; i > 0; i >>= 1)
      val[i] = Monoid::op(val[2 * i], val[2 * i + 1]);
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  V<P> ps(n);
  V<> xs(n);
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    ps[i] = {i, x, y};
    xs[i] = x;
  }
  sort(begin(xs), end(xs));
  xs.erase(unique(begin(xs), end(xs)), end(xs));
  for (int i = 0; i < n; ++i)
    ps[i].x = distance(begin(xs), lower_bound(begin(xs), end(xs), ps[i].x));
  VV<P> init(xs.size());
  for (int i = 0; i < n; ++i)
    init[ps[i].x].push_back(ps[i]);
  for (auto &&v : init)
    sort(begin(v), end(v), comp_y);
  SegmentTree<Monoid> st(begin(init), end(init));
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int xl, xr, yl, yr;
    cin >> xl >> xr >> yl >> yr, ++xr, ++yr;
    xl = distance(begin(xs), lower_bound(begin(xs), end(xs), xl));
    xr = distance(begin(xs), lower_bound(begin(xs), end(xs), xr));
    auto res = st.get(xl, xr, yl, yr);
    sort(begin(res), end(res), comp_id);
    for (const auto &e : res)
      cout << e.id << '\\n';
    cout << '\\n';
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
template <class T = int> using V = vector<T>;
template <class T = int> using VV = V<V<T>>;
template <class T> void assign(V<T> &v, int n, const T &a = T()) {
  v.assign(n, a);
}
template <class T, class... Args>
void assign(V<T> &v, int n, const Args &...args) {
  v.resize(n);
  for (auto &&e : v)
    assign(e, args...);
}

struct P {
  int id, x, y;
};
auto comp_id = [](const P &lhs, const P &rhs) { return lhs.id < rhs.id; };
auto comp_x = [](const P &lhs, const P &rhs) { return lhs.x < rhs.x; };
auto comp_y = [](const P &lhs, const P &rhs) { return lhs.y < rhs.y; };

struct Monoid {
  using T = V<P>;
  static T op(const T &lhs, const T &rhs) {
    T res;
    merge(begin(lhs), end(lhs), begin(rhs), end(rhs), back_inserter(res),
          comp_y);
    return move(res);
  }
  static T e() { return T(); }
};

template <class Monoid> struct SegmentTree {
  using T = typename Monoid::T;

  const int n;
  V<T> val;

  SegmentTree(int n) : n(n), val(2 * n, Monoid::e()) {}
  template <class Itr>
  SegmentTree(Itr first, Itr last)
      : n(distance(first, last)), val(2 * n, Monoid::e()) {
    copy(first, last, next(begin(val), n));
    build();
  }

  T &at(int i) { return val[i + n]; }

  void build() {
    for (int i = n - 1; i > 0; --i)
      val[i] = Monoid::op(val[2 * i], val[2 * i + 1]);
  }

  T get(int l, int r) const {
    T resl = Monoid::e(), resr = Monoid::e();
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        resl = Monoid::op(resl, val[l++]);
      if (r & 1)
        resr = Monoid::op(val[--r], resr);
    }
    return Monoid::op(resl, resr);
  }

  void set(int i, const T &a) {
    for (val[i += n] = a, i >>= 1; i > 0; i >>= 1)
      val[i] = Monoid::op(val[2 * i], val[2 * i + 1]);
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  V<P> ps(n);
  V<> xs(n);
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    ps[i] = {i, x, y};
    xs[i] = x;
  }
  sort(begin(xs), end(xs));
  xs.erase(unique(begin(xs), end(xs)), end(xs));
  for (int i = 0; i < n; ++i)
    ps[i].x = distance(begin(xs), lower_bound(begin(xs), end(xs), ps[i].x));
  VV<P> init(xs.size());
  for (int i = 0; i < n; ++i)
    init[ps[i].x].push_back(ps[i]);
  for (auto &&v : init)
    sort(begin(v), end(v), comp_y);
  SegmentTree<Monoid> st(begin(init), end(init));
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int xl, xr, yl, yr;
    cin >> xl >> xr >> yl >> yr, ++xr, ++yr;
    xl = distance(begin(xs), lower_bound(begin(xs), end(xs), xl));
    xr = distance(begin(xs), lower_bound(begin(xs), end(xs), xr));
    auto res = st.get(xl, xr);
    auto first = lower_bound(begin(res), end(res), P{-1, 0, yl}, comp_y);
    auto last = lower_bound(begin(res), end(res), P{-1, 0, yr}, comp_y);
    sort(first, last, comp_id);
    while (first != last) {
      cout << first->id << '\\n';
      ++first;
    }
    cout << '\\n';
  }
}