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

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;

struct Node {
  using NP = const Node *;

  ll sm, now;
  ll dsm;
  /*
   init_leaf, update, push
  */
  void init_leaf(ll d) {
    sm = now = 0;
    dsm = d;
  }
  void update() {
    dsm = l->dsm + r->dsm;
    sm = l->sm + r->sm + now * dsm;
  }
  void lzdata(ll x) {
    sm += dsm * x;
    now += x;
  }
  void push() {}
  /// push???const?????¢?????????????????§??????
  void push() const { const_cast<Node *>(this)->push(); }

  NP add(int a, int b) const {
    if (b <= 0 or sz <= a)
      return this;
    if (a <= 0 and sz <= b) {
      auto n = make(this);
      n->lzdata(1);
      return n;
    }
    push();
    int u = sm;
    auto nl = l->add(a, b);
    auto nr = r->add(a - sz / 2, b - sz / 2);
    auto n = make(this);
    n->l = nl;
    n->r = nr;
    n->update();
    return n;
  }
  ll get(int a, int b, ll cur = 0) const {
    if (b <= 0 or sz <= a)
      return 0;
    if (a <= 0 and sz <= b) {
      return sm + cur * dsm;
    }
    push();
    return l->get(a, b, cur + now) + r->get(a - sz / 2, b - sz / 2, cur + now);
  }

  NP l, r;
  int sz;
  Node() {}
  Node(int sz, ll d[]) : sz(sz), now(0) {
    if (sz == 1) {
      init_leaf(d[0]);
      return;
    }
    l = new Node(sz / 2, d);
    r = new Node(sz - sz / 2, d + sz / 2);
    update();
  }
  static Node *make(NP x) {
    auto n = new Node();
    *n = *x;
    return n;
  }
};

int main() {
  int n, m, q;
  cin >> n >> m >> q;
  const int MM = 100100;
  const int MQ = 100100;
  const int MX = (MM + MQ) * 2;
  const int MY = MM;
  static int a[MM], b[MM], v[MM];
  static vector<int> g[MY];
  static int x[MQ], y[MQ];
  static ll j[MQ];
  vector<int> vl, xl;
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i] >> v[i];
    b[i]++;
    vl.push_back(v[i]);
    xl.push_back(a[i]);
    xl.push_back(b[i]);
  }
  for (int i = 0; i < q; i++) {
    cin >> x[i] >> y[i] >> j[i];
    y[i]++;
    xl.push_back(x[i]);
    xl.push_back(y[i]);
  }
  sort(vl.begin(), vl.end());
  vl.erase(unique(vl.begin(), vl.end()), vl.end());

  for (int i = 0; i < m; i++) {
    v[i] = lower_bound(vl.begin(), vl.end(), v[i]) - vl.begin();
    g[v[i]].push_back(i);
  }

  sort(xl.begin(), xl.end());
  xl.erase(unique(xl.begin(), xl.end()), xl.end());

  auto x2xl = [&](const int &x) {
    return lower_bound(xl.begin(), xl.end(), x) - xl.begin();
  };

  for (int i = 0; i < m; i++) {
    a[i] = x2xl(a[i]);
    b[i] = x2xl(b[i]);
  }
  for (int i = 0; i < q; i++) {
    x[i] = x2xl(x[i]);
    y[i] = x2xl(y[i]);
  }

  // for (int i = 0; i < m; i++) {
  //     printf("%d %d %d\\n", a[i], b[i], v[i]);
  // }
  // for (int i = 0; i < q; i++) {
  //     printf("%d %d %lld\\n", x[i], y[i], j[i]);
  // }
  static ll deg[MX];
  for (int i = 0; i < (int)xl.size() - 1; i++) {
    deg[i] = xl[i + 1] - xl[i];
  }
  static const Node *tr[MY];
  tr[0] = new Node(MX, deg);
  for (int i = 1; i < MY; i++) {
    tr[i] = tr[i - 1];
    for (int d : g[i - 1]) {
      tr[i] = tr[i]->add(a[d], b[d]);
    }
  }
  for (int i = 0; i < q; i++) {
    int l = 0, r = MY - 1;
    while (r - l > 1) {
      int md = (l + r) / 2;
      if (tr[md]->get(x[i], y[i]) < j[i]) {
        l = md;
      } else {
        r = md;
      }
    }
    //        printf("%d %d\\n", l, r);
    cout << vl[l] << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;

struct Node {
  using NP = const Node *;

  ll sm;
  int lz;
  int dsm;
  /*
   init_leaf, update, push
  */
  void init_leaf(ll d) {
    sm = lz = 0;
    dsm = d;
  }
  void update() {
    sm = l->sm + r->sm;
    dsm = l->dsm + r->dsm;
  }
  void lzdata(ll x) {
    lz += x;
    sm += dsm * x;
  }
  void push() {
    if (lz) {
      auto nl = make(l);
      auto nr = make(r);
      nl->lzdata(lz);
      nr->lzdata(lz);
      l = nl;
      r = nr;
      lz = 0;
    }
  }
  /// push???const?????¢?????????????????§??????
  void push() const { const_cast<Node *>(this)->push(); }

  NP add(int a, int b) const {
    if (b <= 0 or sz <= a)
      return this;
    if (a <= 0 and sz <= b) {
      auto n = make(this);
      n->lzdata(1);
      return n;
    }
    push();
    auto nl = l->add(a, b);
    auto nr = r->add(a - sz / 2, b - sz / 2);
    return make(nl, nr);
  }
  ll get(int a, int b) const {
    if (b <= 0 or sz <= a)
      return 0;
    if (a <= 0 and sz <= b) {
      return sm;
    }
    push();
    return l->get(a, b) + r->get(a - sz / 2, b - sz / 2);
  }

  NP l, r;
  int sz;
  Node() {}
  Node(int sz, ll d[]) : sz(sz), lz(0) {
    if (sz == 1) {
      init_leaf(d[0]);
      return;
    }
    l = new Node(sz / 2, d);
    r = new Node(sz - sz / 2, d + sz / 2);
    update();
  }
  static Node *make(NP x) {
    auto n = new Node();
    *n = *x;
    return n;
  }
  static Node *make(NP l, NP r) {
    auto n = new Node();
    n->l = l;
    n->r = r;
    n->sz = l->sz + r->sz;
    n->update();
    return n;
  }
};

int main() {
  int n, m, q;
  cin >> n >> m >> q;
  const int MM = 100100;
  const int MQ = 100100;
  const int MX = MM + MQ;
  const int MY = MM;
  static int a[MM], b[MM], v[MM];
  static vector<int> g[MY];
  static int x[MQ], y[MQ];
  static ll j[MQ];
  vector<int> vl, xl;
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i] >> v[i];
    b[i]++;
    vl.push_back(v[i]);
    xl.push_back(a[i]);
    xl.push_back(b[i]);
  }
  for (int i = 0; i < q; i++) {
    cin >> x[i] >> y[i] >> j[i];
    y[i]++;
    xl.push_back(x[i]);
    xl.push_back(y[i]);
  }
  sort(vl.begin(), vl.end());
  vl.erase(unique(vl.begin(), vl.end()), vl.end());

  for (int i = 0; i < m; i++) {
    v[i] = lower_bound(vl.begin(), vl.end(), v[i]) - vl.begin();
    g[v[i]].push_back(i);
  }

  sort(xl.begin(), xl.end());
  xl.erase(unique(xl.begin(), xl.end()), xl.end());

  auto x2xl = [&](const int &x) {
    return lower_bound(xl.begin(), xl.end(), x) - xl.begin();
  };

  for (int i = 0; i < m; i++) {
    a[i] = x2xl(a[i]);
    b[i] = x2xl(b[i]);
  }
  for (int i = 0; i < q; i++) {
    x[i] = x2xl(x[i]);
    y[i] = x2xl(y[i]);
  }

  // for (int i = 0; i < m; i++) {
  //     printf("%d %d %d\\n", a[i], b[i], v[i]);
  // }
  // for (int i = 0; i < q; i++) {
  //     printf("%d %d %lld\\n", x[i], y[i], j[i]);
  // }
  static ll deg[MX];
  for (int i = 0; i < (int)xl.size() - 1; i++) {
    deg[i] = xl[i + 1] - xl[i];
  }
  static const Node *tr[MY];
  tr[0] = new Node(MX, deg);
  for (int i = 1; i < MY; i++) {
    tr[i] = tr[i - 1];
    for (int d : g[i - 1]) {
      tr[i] = tr[i]->add(a[d], b[d]);
    }
  }
  for (int i = 0; i < q; i++) {
    int l = 0, r = MY - 1;
    while (r - l > 1) {
      int md = (l + r) / 2;
      if (tr[md]->get(x[i], y[i]) < j[i]) {
        l = md;
      } else {
        r = md;
      }
    }
    //        printf("%d %d\\n", l, r);
    cout << vl[l] << endl;
  }
  return 0;
}