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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define MP(x, y) make_pair((x), (y))
#define PB(x) push_back(x)
typedef long long LL;
// typedef unsigned __int64 ULL;
/* ****************** */
const int INF = 100011122;
const double INFF = 1e100;
const double eps = 1e-8;
const LL mod = 1000000007;
const int NN = 300010;
const int MM = 1000010;
/* ****************** */

const int limit = 1000000;

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

struct node {
  int x, y, z;
  bool operator<(const node &tt) const { return x < tt.x; }
} a[NN];
struct node1 {
  int x, y, z, id;
  bool operator<(const node1 &tt) const {
    if (y != tt.y)
      return y < tt.y;
    return z > tt.z;
  }
} b[NN];
int dp[NN];
int c[2][limit + 1];

int lowbit(int x) { return x & (-x); }
void update(int fg, int x, int val) {
  for (; x <= limit; x += lowbit(x))
    c[fg][x] = max(c[fg][x], val);
}
int get_max(int fg, int x) {
  int ans = 0;
  for (; x > 0; x -= lowbit(x))
    ans = max(ans, c[fg][x]);
  return ans;
}
void clr_update(int fg, int x) {
  for (; x <= limit; x += lowbit(x))
    c[fg][x] = 0;
}

void cdq(int l, int r) {
  if (l == r) {
    dp[l] = max(dp[l], 1);
    return;
  }
  int mid = (l + r) >> 1;
  int t, i, cnt = 0, tx = a[mid + 1].x;

  cdq(l, mid);

  for (i = l; i <= r; i++) {
    b[cnt].x = a[i].x;
    b[cnt].y = a[i].y;
    b[cnt].z = a[i].z;
    b[cnt].id = i;
    cnt++;
  }
  sort(b, b + cnt);
  for (i = 0; i < cnt; i++) {
    if (b[i].id <= mid) {
      update(1, b[i].z, dp[b[i].id]);
      if (b[i].x != tx)
        update(0, b[i].z, dp[b[i].id]);
    } else {
      if (b[i].x == tx)
        t = get_max(0, b[i].z - 1);
      else
        t = get_max(1, b[i].z - 1);

      dp[b[i].id] = max(dp[b[i].id], t + 1);
    }
  }
  for (i = 0; i < cnt; i++)
    if (b[i].id <= mid) {
      clr_update(1, b[i].z);
      if (b[i].x != tx)
        clr_update(0, b[i].z);
    }

  cdq(mid + 1, r);
}

void solve(int n) {
  int i, ans = 0;
  sort(a + 1, a + 1 + n);

  memset(c, 0, sizeof(c));
  memset(dp, 0, sizeof(dp));

  cdq(1, n);

  for (i = 1; i <= n; i++)
    ans = max(ans, dp[i]);

  printf("%d\\n", ans);
}

int main() {
  int m, n, i;
  while (scanf("%d%d%d%d", &m, &n, &aa, &bb) != EOF) {
    if (m == 0 && n == 0)
      break;

    for (i = 1; i <= m; i++) {
      scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
      a[i].x++;
      a[i].y++;
      a[i].z++;
    }
    for (i = 1; i <= n; i++) {
      a[i + m].x = rr();
      a[i + m].y = rr();
      a[i + m].z = rr();

      a[i + m].x++;
      a[i + m].y++;
      a[i + m].z++;
    }

    solve(n + m);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <vector>
typedef long long LL;
int num[50000010], a[1000010], h[1000010], tot;
int A, B, C = ~(1 << 31), M = (1 << 16) - 1;
int myRand() {
  A = 36969 * (A & M) + (A >> 16);
  B = 18000 * (B & M) + (B >> 16);
  return (C & ((A << 16) + B)) % 1000000;
}
int N, NN;
struct V {
  int x, y, z;
  bool operator<(const V &t) const { return x < t.x; }
} v[300010];
int yn, zn;
std::map<LL, int> node;
void genNode() {
  node.clear();
  tot = 0;
  for (int i = 0; i < N; i++) {
    for (int y = v[i].y; y <= yn; y += y & -y) {
      for (int z = v[i].z; z <= zn; z += z & -z) {
        LL k = y * 1000000ll + z;
        if (!node[k]) {
          node[k] = ++tot;
          a[tot] = 0;
        }
      }
    }
    for (int y = v[i].y - 1; y > 0; y -= y & -y) {
      for (int z = v[i].z - 1; z > 0; z -= z & -z) {
        LL k = y * 1000000ll + z;
        if (!node[k]) {
          node[k] = ++tot;
          a[tot] = 0;
        }
      }
    }
  }
}
void update(int y, int z, int v) {
  for (int i = y; i <= yn; i += i & -i) {
    for (int j = z; j <= zn; j += j & -j) {
      int k = node[i * 1000000ll + j];
      a[k] = std::max(a[k], v);
    }
  }
}
int query(int y, int z) {
  int max = 0;
  for (int i = y; i > 0; i -= i & -i) {
    for (int j = z; j > 0; j -= j & -j) {
      int k = node[i * 1000000ll + j];
      max = std::max(max, a[k]);
    }
  }
  return max;
}
void process() {
  int ans = 0;
  for (int i = 0; i < N; i++) {
    ans = std::max(ans, query(v[i].y - 1, v[i].z - 1) + 1);
    update(v[i].y, v[i].z, ans);
  }
  printf("%d\\n", ans);
}
int main() {
  // freopen("test.in", "rb", stdin);
  while (scanf("%d%d%d%d", &N, &NN, &A, &B), N + NN > 0) {
    for (int i = 0; i < N; i++) {
      scanf("%d%d%d", &v[i].x, &v[i].y, &v[i].z);
    }
    for (int i = 0; i < NN; i++) {
      v[N].x = myRand();
      v[N].y = myRand();
      v[N].z = myRand();
      ++N;
    }
    std::sort(v, v + N);
    // yn
    yn = 0;
    for (int i = 0; i < N; i++) {
      a[yn++] = v[i].y;
      if (v[i].y > 0) {
        a[yn++] = v[i].y - 1;
      }
    }
    std::sort(a, a + yn);
    yn = std::unique(a, a + yn) - a;
    for (int i = 0; i < yn; i++) {
      h[a[i]] = i + 1;
    }
    for (int i = 0; i < N; i++) {
      v[i].y = h[v[i].y];
    }
    // zn
    zn = 0;
    for (int i = 0; i < N; i++) {
      a[zn++] = v[i].z;
      if (v[i].z > 0) {
        a[zn++] = v[i].z - 1;
      }
    }
    std::sort(a, a + zn);
    zn = std::unique(a, a + zn) - a;
    for (int i = 0; i < zn; i++) {
      h[a[i]] = i + 1;
    }
    for (int i = 0; i < N; i++) {
      v[i].z = h[v[i].z];
    }
    genNode();
    process();
  }
  return 0;
}