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

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

#define rep(i, N) for (int i = 0; i < N; i++)
#define pb push_back

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<int, ll> i_ll;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge {
  int v;
  ll w;
};

const int MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
int INF = INT_MAX / 2;

struct bit {
  vector<int> a;
  bit(int N = 0) : a(N + 1) {}
  int get(int i) {
    int val = 0;
    for (; i; i -= i & -i)
      val = max(val, a[i]);
    return val;
  }
  void set(int i, int val) {
    for (i++; i < a.size(); i += i & -i)
      a[i] = max(a[i], val);
  }
};

struct segtree {
  segtree *lch, *rch;
  int N, val;
  segtree(int _N) : N(_N), val(0) {
    if (N > 1) {
      int n = N / 2;
      lch = new segtree(n);
      rch = new segtree(N - n);
    }
  }
  ~segtree() {
    if (N > 1) {
      delete lch;
      delete rch;
    }
  }
  int get(int l, int r) {
    if (r <= 0 || N <= l)
      return 0;
    if (l <= 0 && N <= r)
      return val;
    int n = N / 2;
    return max(lch->get(l, r), rch->get(l - n, r - n));
  }
  void set(int i, int _val) {
    if (N == 1) {
      val = max(val, _val);
      return;
    }
    int n = N / 2;
    if (i < n)
      lch->set(i, _val);
    else
      rch->set(i - n, _val);
    val = max(lch->val, rch->val);
  }
};

struct segtree_2d {
  segtree_2d *lch, *rch;
  int H;
  vector<int> X;
  bit bt;
  segtree_2d(int _H, vector<int> &y, vector<int> &x) : H(_H) {
    if (H > 1) {
      int h = H / 2, N = y.size();
      vector<int> y1, x1, y2, x2;
      rep(i, N) if (y[i] < h) y1.pb(y[i]), x1.pb(x[i]);
      else y2.pb(y[i] - h), x2.pb(x[i]);
      lch = new segtree_2d(h, y1, x1);
      rch = new segtree_2d(H - h, y2, x2);
    }
    X = x;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
    bt = bit(X.size()); // new segtree(X.size());
  }
  ~segtree_2d() {
    if (H > 1) {
      delete lch;
      delete rch;
    }
  }
  int get(int yl, int yr, int xl, int xr) {
    if (yr <= 0 || H <= yl)
      return 0;
    if (yl <= 0 && H <= yr) {
      int l = lower_bound(X.begin(), X.end(), xl) - X.begin();
      int r = lower_bound(X.begin(), X.end(), xr) - X.begin();
      return bt.get(r);
    }
    int h = H / 2;
    return max(lch->get(yl, yr, xl, xr), rch->get(yl - h, yr - h, xl, xr));
  }
  void set(int y, int x, int _val) {
    if (H > 1) {
      int h = H / 2;
      if (y < h)
        lch->set(y, x, _val);
      else
        rch->set(y - h, x, _val);
    }
    int i = lower_bound(X.begin(), X.end(), x) - X.begin();
    bt.set(i, _val);
  }
};

int a, b, C = ~(1 << 31), M = (1 << 16) - 1;
int r() {
  a = 36969 * (a & M) + (a >> 16);
  b = 18000 * (b & M) + (b >> 16);
  return (C & ((a << 16) + b)) % 1000000;
}

int compress(vector<int> &a) {
  vector<int> A = a;
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  for (int &x : a)
    x = lower_bound(A.begin(), A.end(), x) - A.begin();
  return A.size();
}

struct dice {
  mt19937 mt;
  dice() {
    random_device rd;
    mt = mt19937(rd());
  }
  int operator()(int x) { return this->operator()(0, x - 1); }
  int operator()(int x, int y) {
    uniform_int_distribution<int> dist(x, y);
    return dist(mt);
  }
} dc;

int main() {
  /*
  for (;;) {
          cout << 'a' << endl;
          int N = 10000;
          vector<int> y(N), x(N), w(N);
          rep(i, N) y[i] = dc(100), x[i] = dc(100), w[i] = dc(100);
          segtree_2d* st = new segtree_2d(10000, y, x);
          rep(i, N) st->set(y[i], x[i], w[i]);
          rep(i, N) {
                  int ans1 = st->get(0, y[i], 0, x[i]);
                  int ans2 = 0;
                  rep(j, N) if (y[j] < y[i] && x[j] < x[i])
                          ans2 = max(ans2, w[j]);
                  if (ans1 != ans2) cout << "ERR" << endl;
          }
  }
  */
  for (;;) {
    int M, N, A, B;
    M = 0;
    N = 300000;
    A = dc(1, 1 << 16);
    B = dc(1, 1 << 16);
    scanf("%d%d%d%d", &M, &N, &A, &B);
    if (!(M + N))
      break;
    vector<int> x(M + N), y(M + N), z(M + N);
    rep(i, M) scanf("%d%d%d", &x[i], &y[i], &z[i]);
    a = A;
    b = B;
    rep(i, N) x[M + i] = r(), y[M + i] = r(), z[M + i] = r();
    N = M + N;
    int W = compress(x), H = compress(y), D = compress(z);
    segtree_2d *st = new segtree_2d(H, y, x);
    vector<vector<int>> v(D);
    rep(i, N) v[z[i]].pb(i);
    vector<int> len(N);
    rep(z, D) {
      for (int i : v[z])
        len[i] = st->get(0, y[i], 0, x[i]) + 1;
      for (int i : v[z])
        st->set(y[i], x[i], len[i]);
    }
    delete st;
    int ans = 0;
    rep(i, N) ans = max(ans, len[i]);
    printf("%d\\n", ans);
  }
}

Error: MLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

#define rep(i, N) for (int i = 0; i < N; i++)
#define pb push_back

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<int, ll> i_ll;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge {
  int v;
  ll w;
};

const int MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
int INF = INT_MAX / 2;

struct segtree {
  segtree *lch, *rch;
  int N, val;
  segtree(int _N) : N(_N), val(0) {
    if (N > 1) {
      int n = N / 2;
      lch = new segtree(n);
      rch = new segtree(N - n);
    }
  }
  ~segtree() {
    if (N > 1) {
      delete lch;
      delete rch;
    }
  }
  int get(int l, int r) {
    if (r <= 0 || N <= l)
      return 0;
    if (l <= 0 && N <= r)
      return val;
    int n = N / 2;
    return max(lch->get(l, r), rch->get(l - n, r - n));
  }
  void set(int i, int _val) {
    if (N == 1) {
      val = max(val, _val);
      return;
    }
    int n = N / 2;
    if (i < n)
      lch->set(i, _val);
    else
      rch->set(i - n, _val);
    val = max(lch->val, rch->val);
  }
};

struct segtree_2d {
  segtree_2d *lch, *rch;
  int H;
  vector<int> X;
  segtree *st;
  segtree_2d(int _H, vector<int> &y, vector<int> &x) : H(_H) {
    if (H > 1) {
      int h = H / 2, N = y.size();
      vector<int> y1, x1, y2, x2;
      rep(i, N) if (y[i] < h) y1.pb(y[i]), x1.pb(x[i]);
      else y2.pb(y[i] - h), x2.pb(x[i]);
      lch = new segtree_2d(h, y1, x1);
      rch = new segtree_2d(H - h, y2, x2);
    }
    X = x;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
    st = new segtree(X.size());
  }
  ~segtree_2d() {
    if (H > 1) {
      delete lch;
      delete rch;
    }
    X.clear();
    delete st;
  }
  int get(int yl, int yr, int xl, int xr) {
    if (yr <= 0 || H <= yl)
      return 0;
    if (yl <= 0 && H <= yr) {
      int l = lower_bound(X.begin(), X.end(), xl) - X.begin();
      int r = lower_bound(X.begin(), X.end(), xr) - X.begin();
      return st->get(l, r);
    }
    int h = H / 2;
    return max(lch->get(yl, yr, xl, xr), rch->get(yl - h, yr - h, xl, xr));
  }
  void set(int y, int x, int _val) {
    if (H > 1) {
      int h = H / 2;
      if (y < h)
        lch->set(y, x, _val);
      else
        rch->set(y - h, x, _val);
    }
    int i = lower_bound(X.begin(), X.end(), x) - X.begin();
    st->set(i, _val);
  }
};

int a, b, C = ~(1 << 31), M = (1 << 16) - 1;
int r() {
  a = 36969 * (a & M) + (a >> 16);
  b = 18000 * (b & M) + (b >> 16);
  return (C & ((a << 16) + b)) % 1000000;
}

int compress(vector<int> &a) {
  vector<int> A = a;
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  for (int &x : a)
    x = lower_bound(A.begin(), A.end(), x) - A.begin();
  return A.size();
}

struct dice {
  mt19937 mt;
  dice() {
    random_device rd;
    mt = mt19937(rd());
  }
  int operator()(int x) { return this->operator()(0, x - 1); }
  int operator()(int x, int y) {
    uniform_int_distribution<int> dist(x, y);
    return dist(mt);
  }
} dc;

int main() {
  /*
  for (;;) {
          cout << 'a' << endl;
          int N = 10000;
          vector<int> y(N), x(N), w(N);
          rep(i, N) y[i] = dc(100), x[i] = dc(100), w[i] = dc(100);
          segtree_2d* st = new segtree_2d(10000, y, x);
          rep(i, N) st->set(y[i], x[i], w[i]);
          rep(i, N) {
                  int ans1 = st->get(0, y[i], 0, x[i]);
                  int ans2 = 0;
                  rep(j, N) if (y[j] < y[i] && x[j] < x[i])
                          ans2 = max(ans2, w[j]);
                  if (ans1 != ans2) cout << "ERR" << endl;
          }
  }
  */
  for (;;) {
    int M, N, A, B;
    M = 0;
    N = 300000;
    A = dc(1, 1 << 16);
    B = dc(1, 1 << 16);
    scanf("%d%d%d%d", &M, &N, &A, &B);
    if (!(M + N))
      break;
    vector<int> x(M + N), y(M + N), z(M + N);
    rep(i, M) scanf("%d%d%d", &x[i], &y[i], &z[i]);
    a = A;
    b = B;
    rep(i, N) x[M + i] = r(), y[M + i] = r(), z[M + i] = r();
    N = M + N;
    int W = compress(x), H = compress(y), D = compress(z);
    segtree_2d *st = new segtree_2d(H, y, x);
    vector<vector<int>> v(D);
    rep(i, N) v[z[i]].pb(i);
    vector<int> len(N);
    rep(z, D) {
      for (int i : v[z])
        len[i] = st->get(0, y[i], 0, x[i]) + 1;
      for (int i : v[z])
        st->set(y[i], x[i], len[i]);
    }
    delete st;
    int ans = 0;
    rep(i, N) ans = max(ans, len[i]);
    printf("%d\\n", ans);
  }
}