Problem p00328 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <cstdio>
#include <iostream>
#include <vector>
#define _USE_MATH_DEFINES
#include <algorithm>
#include <array>
#include <chrono>
#include <complex>
#include <cstring>
#include <functional>
#include <limits.h>
#include <map>
#include <math.h>
#include <nmmintrin.h>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <unordered_map>
const double EPS = 1e-8;
#define Scan(a)                                                                \\
  int a;                                                                       \\
  scanf("%d", &a);
#define ScanS(a)                                                               \\
  char a[500];                                                                 \\
  scanf("%s", a);
#define rep(i, s, n) for (int i = (s); (n) > i; i++)
#define REP(i, n) rep(i, 0, n)
#define RANGE(x, a, b) ((a) <= (x) && (x) <= (b))
#define DUPLE(a, b, c, d)                                                      \\
  (RANGE(a, c, d) || RANGE(b, c, d) || RANGE(c, a, b) || RANGE(d, a, b))
#define INCLU(a, b, c, d) (RANGE(a, c, d) && (b, c, d))
#define PW(x) ((x) * (x))
#define ALL(x) (x).begin(), (x).end()
#define MODU 1000000007
#define bitcheck(a, b) ((a >> b) & 1)
#define bitset(a, b) (a |= (1 << b))
#define bitunset(a, b) (a &= ~(1 << b))
#define MP(a, b) make_pair((a), (b))
#define Manh(a, b) (abs((a).first-(b).first) + abs((a).second - ((b).second))
#define pritnf printf
#define scnaf scanf
#define itn int
#ifdef _MSC_VER
#define __builtin_popcount _mm_popcnt_u32
#define __builtin_popcountll _mm_popcnt_u64
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
class Lazy_Segment_Tree { // 0-indexed ??????
public:
  vector<set<int>> data;
  int n;
  Lazy_Segment_Tree(int a) : n(1) {
    while (n < a)
      n *= 2;
    data.resize(n * 2 - 1);
  }
  void op(int a, int b, int v, int num = 0, int base = 1) {
    int l = (num + 1 - base) * (n / base), r = l + n / base;
    if (a == l && b == r) {
      data[num].insert(v);
    } else {
      int nr = (l + r) / 2;
      if (nr > a)
        op(a, min(b, nr), v, num * 2 + 1, base * 2);
      if (nr < b)
        op(max(a, nr), b, v, num * 2 + 2, base * 2);
    }
  }

  bool query(int a, pii que, int num = 0, int base = 1) {
    int l = (num + 1 - base) * (n / base), r = l + n / base;

    if (r - l == 1) {
      return data[num].lower_bound(que.first) !=
             data[num].upper_bound(que.second);
    } else {
      int nr = (l + r) / 2;
      bool ret =
          data[num].lower_bound(que.first) != data[num].upper_bound(que.second);
      if (nr > a)
        ret |= query(a, que, num * 2 + 1, base * 2);
      else
        ret |= query(a, que, num * 2 + 2, base * 2);
      return ret;
    }
  }
};

int main() {
  int n;
  cin >> n;

  map<int, int> x, y;
  vector<int> xz, yz;
  vector<pair<pii, pii>> ln;
  REP(i, n) {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);

    ln.push_back({{min(a, c), min(b, d)}, {max(a, c), max(b, d)}});

    xz.push_back(a);
    xz.push_back(c);
    yz.push_back(b);
    yz.push_back(d);
  }

  sort(ALL(xz));
  sort(ALL(yz));
  xz.erase(unique(ALL(xz)), xz.end());
  yz.erase(unique(ALL(yz)), yz.end());

  REP(i, xz.size())
  x[xz[i]] = i;
  REP(i, yz.size())
  y[yz[i]] = i;

  Lazy_Segment_Tree xs(xz.size()), ys(yz.size());

  for (auto &itr : ln) {
    itr.first.first = x[itr.first.first];
    itr.first.second = y[itr.first.second];
    itr.second.first = x[itr.second.first];
    itr.second.second = y[itr.second.second];
  }

  vector<set<pair<int, bool>>> px(yz.size()), py(xz.size());

  for (auto cl : ln) {

    if (cl.first.first == cl.second.first) {
      int an = xs.query(cl.first.first, {cl.first.second, cl.second.second});

      auto itr = py[cl.first.first].upper_bound({cl.second.second, 1});
      an |= py[cl.first.first].lower_bound({cl.first.second, 0}) != itr;
      if (itr != py[cl.first.first].end())
        an |= py[cl.first.first].upper_bound({cl.second.second, 1})->second;

      printf("%d\\n", !an);
      if (!an) {
        ys.op(cl.first.second, cl.second.second + 1, cl.first.first);
        py[cl.first.first].insert({cl.first.second, 0});
        py[cl.first.first].insert({cl.second.second, 1});
      }
    } else {
      int an = ys.query(cl.first.second, {cl.first.first, cl.second.first});
      auto itr = px[cl.first.second].upper_bound({cl.second.first, 1});
      an |= px[cl.first.second].lower_bound({cl.first.first, 0}) != itr;
      if (itr != px[cl.first.second].end())
        an |= itr->second;
      printf("%d\\n", !an);

      if (!an) {
        xs.op(cl.first.first, cl.second.first + 1, cl.first.second);
        px[cl.first.second].insert({cl.first.first, 0});
        px[cl.first.second].insert({cl.second.first, 1});
      }
    }
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <vector>
#define _USE_MATH_DEFINES
#include <algorithm>
#include <array>
#include <chrono>
#include <complex>
#include <cstring>
#include <functional>
#include <limits.h>
#include <map>
#include <math.h>
#include <nmmintrin.h>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <unordered_map>
const double EPS = 1e-8;
#define Scan(a)                                                                \\
  int a;                                                                       \\
  scanf("%d", &a);
#define ScanS(a)                                                               \\
  char a[500];                                                                 \\
  scanf("%s", a);
#define rep(i, s, n) for (int i = (s); (n) > i; i++)
#define REP(i, n) rep(i, 0, n)
#define RANGE(x, a, b) ((a) <= (x) && (x) <= (b))
#define DUPLE(a, b, c, d)                                                      \\
  (RANGE(a, c, d) || RANGE(b, c, d) || RANGE(c, a, b) || RANGE(d, a, b))
#define INCLU(a, b, c, d) (RANGE(a, c, d) && (b, c, d))
#define PW(x) ((x) * (x))
#define ALL(x) (x).begin(), (x).end()
#define MODU 1000000007
#define bitcheck(a, b) ((a >> b) & 1)
#define bitset(a, b) (a |= (1 << b))
#define bitunset(a, b) (a &= ~(1 << b))
#define MP(a, b) make_pair((a), (b))
#define Manh(a, b) (abs((a).first-(b).first) + abs((a).second - ((b).second))
#define pritnf printf
#define scnaf scanf
#define itn int
#ifdef _MSC_VER
#define __builtin_popcount _mm_popcnt_u32
#define __builtin_popcountll _mm_popcnt_u64
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
class Lazy_Segment_Tree { // 0-indexed ??????
public:
  vector<set<int>> data, lazy;
  vector<bool> isupd;
  int n;
  Lazy_Segment_Tree(int a) : n(1) {
    while (n < a)
      n *= 2;
    data.resize(n * 2 - 1);
    lazy.resize(n * 2 - 1);
    isupd.resize(n * 2 - 1);
  }

  void prop(int num, int s) {
    if (isupd[num]) {
      data[num].insert(ALL(lazy[num]));
      if (num < n - 1) {
        lazy[num * 2 + 1].insert(ALL(lazy[num]));
        lazy[num * 2 + 2].insert(ALL(lazy[num]));
        isupd[num * 2 + 1] = 1;
        isupd[num * 2 + 2] = 1;
      }
      lazy[num].clear();
      isupd[num] = 0;
    }
  }
  void op(int a, int b, int v, int num = 0, int base = 1) {
    int l = (num + 1 - base) * (n / base), r = l + n / base;
    prop(num, r - l);
    if (a == l && b == r) {
      isupd[num] = 1;
      lazy[num].insert(v);
      prop(num, r - l);
    } else {
      int nr = (l + r) / 2;
      if (nr > a)
        op(a, min(b, nr), v, num * 2 + 1, base * 2);
      if (nr < b)
        op(max(a, nr), b, v, num * 2 + 2, base * 2);
      prop(num * 2 + 1, (r - l) / 2), prop(num * 2 + 2, (r - l) / 2);
    }
  }

  bool query(int a, int b, pii que, int num = 0, int base = 1) {
    int l = (num + 1 - base) * (n / base), r = l + n / base;

    prop(num, r - l);

    if (a == l && b == r) {
      return data[num].lower_bound(que.first) !=
             data[num].upper_bound(que.second);
    } else {
      int nr = (l + r) / 2;
      bool ret = false;
      if (nr > a)
        ret |= query(a, min(b, nr), que, num * 2 + 1, base * 2);
      if (nr < b)
        ret |= query(max(a, nr), b, que, num * 2 + 2, base * 2);
      return ret;
    }
  }
};

int main() {
  int n;
  cin >> n;

  map<int, int> x, y;
  vector<int> xz, yz;
  vector<pair<pii, pii>> ln;
  REP(i, n) {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);

    ln.push_back({{min(a, c), min(b, d)}, {max(a, c), max(b, d)}});

    xz.push_back(a);
    xz.push_back(c);
    yz.push_back(b);
    yz.push_back(d);
  }

  sort(ALL(xz));
  sort(ALL(yz));
  xz.erase(unique(ALL(xz)), xz.end());
  yz.erase(unique(ALL(yz)), yz.end());

  REP(i, xz.size())
  x[xz[i]] = i;
  REP(i, yz.size())
  y[yz[i]] = i;

  Lazy_Segment_Tree xs(xz.size()), ys(yz.size());

  for (auto &itr : ln) {
    itr.first.first = x[itr.first.first];
    itr.first.second = y[itr.first.second];
    itr.second.first = x[itr.second.first];
    itr.second.second = y[itr.second.second];
  }

  vector<set<pair<int, bool>>> px(yz.size()), py(xz.size());

  for (auto cl : ln) {

    if (cl.first.first == cl.second.first) {
      int an = xs.query(cl.first.first, cl.first.first + 1,
                        {cl.first.second, cl.second.second});

      auto itr = py[cl.first.first].upper_bound({cl.second.second, 1});
      an |= py[cl.first.first].lower_bound({cl.first.second, 0}) != itr;
      if (itr != py[cl.first.first].end())
        an |= py[cl.first.first].upper_bound({cl.second.second, 1})->second;

      printf("%d\\n", !an);
      if (!an) {
        ys.op(cl.first.second, cl.second.second + 1, cl.first.first);
        py[cl.first.first].insert({cl.first.second, 0});
        py[cl.first.first].insert({cl.second.second, 1});
      }
    } else {
      int an = ys.query(cl.first.second, cl.first.second + 1,
                        {cl.first.first, cl.second.first});
      auto itr = px[cl.first.second].upper_bound({cl.second.first, 1});
      an |= px[cl.first.second].lower_bound({cl.first.first, 0}) != itr;
      if (itr != px[cl.first.second].end())
        an |= itr->second;
      printf("%d\\n", !an);

      if (!an) {
        xs.op(cl.first.first, cl.second.first + 1, cl.first.second);
        px[cl.first.second].insert({cl.first.first, 0});
        px[cl.first.second].insert({cl.second.first, 1});
      }
    }
  }

  return 0;
}