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

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
int N, M, A, B, C = ~(1 << 31), D = 65535, lim = 1000001, x[300009], y[300009],
                z[300009], p[300009];
vector<int> cp[1000009], bit[1000009];
int func() {
  A = 36969 * (A & D) + (A >> 16);
  B = 18000 * (B & D) + (B >> 16);
  return (C & ((A << 16) + B)) % 1000000;
}
void assign(int px, int py, int val) {
  for (int i = px + 1; i <= lim; i += i & (-i)) {
    int ptr = lower_bound(cp[i].begin(), cp[i].end(), py) - cp[i].begin();
    for (int j = ptr + 1; j <= cp[i].size(); j += j & (-j)) {
      bit[i][j - 1] = max(bit[i][j - 1], val);
    }
  }
}
int query(int px, int py) {
  int ret = 0;
  for (int i = px; i >= 1; i -= i & (-i)) {
    int ptr = lower_bound(cp[i].begin(), cp[i].end(), py) - cp[i].begin();
    for (int j = ptr; j >= 1; j -= j & (-j)) {
      ret = max(ret, bit[i][j - 1]);
    }
  }
  return ret;
}
int main() {
  while (scanf("%d%d%d%d", &N, &M, &A, &B), N + M) {
    for (int i = 0; i < N; ++i)
      scanf("%d%d%d", &x[i], &y[i], &z[i]);
    for (int i = 0; i < M; ++i)
      x[N] = func(), y[N] = func(), z[N] = func(), ++N;
    for (int i = 0; i < N; ++i)
      p[i] = i;
    sort(p, p + N,
         [](int i, int j) { return z[i] != z[j] ? z[i] < z[j] : y[i] > y[j]; });
    for (int i = 0; i <= lim; i++)
      cp[i].clear();
    for (int i = 0; i < N; i++) {
      for (int j = x[p[i]] + 1; j <= lim; j += j & (-j)) {
        cp[j].push_back(y[p[i]]);
      }
    }
    for (int i = 0; i <= lim; i++) {
      sort(cp[i].begin(), cp[i].end());
      cp[i].erase(unique(cp[i].begin(), cp[i].end()), cp[i].end());
      bit[i] = vector<int>(cp[i].size(), 0);
    }
    int ret = 0;
    for (int i = 0; i < N; i++) {
      int res = query(x[p[i]], y[p[i]]);
      assign(x[p[i]], y[p[i]], res + 1);
      ret = max(ret, res + 1);
    }
    printf("%d\\n", ret);
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;
int N, M, A, B, C = ~(1 << 31), D = 65535, lim = 1000001, x[300009], y[300009],
                z[300009], p[300009];
// O(N log^3 N)
map<int, int> bit[1000009];
int func() {
  A = 36969 * (A & D) + (A >> 16);
  B = 18000 * (B & D) + (B >> 16);
  return (C & ((A << 16) + B)) % 1000000;
}
void assign(int px, int py, int val) {
  for (int i = px + 1; i <= lim; i += i & (-i)) {
    for (int j = py + 1; j <= lim; j += j & (-j)) {
      bit[i][j] = max(bit[i][j], val);
    }
  }
}
int query(int px, int py) {
  int ret = 0;
  for (int i = px; i >= 1; i -= i & (-i)) {
    for (int j = py; j >= 1; j -= j & (-j)) {
      ret = max(ret, bit[i][j]);
    }
  }
  return ret;
}
int main() {
  while (scanf("%d%d%d%d", &N, &M, &A, &B), N + M) {
    for (int i = 0; i < N; ++i)
      scanf("%d%d%d", &x[i], &y[i], &z[i]);
    for (int i = 0; i < M; ++i)
      x[N] = func(), y[N] = func(), z[N] = func(), ++N;
    for (int i = 0; i < N; ++i)
      p[i] = i;
    sort(p, p + N,
         [](int i, int j) { return z[i] != z[j] ? z[i] < z[j] : y[i] > y[j]; });
    for (int i = 0; i <= lim; i++)
      bit[i].clear();
    int ret = 0;
    for (int i = 0; i < N; i++) {
      int res = query(x[p[i]], y[p[i]]);
      assign(x[p[i]], y[p[i]], res + 1);
      ret = max(ret, res + 1);
    }
    printf("%d\\n", ret);
  }
  return 0;
}