Problem p00920 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <stdio.h>
using namespace std;
struct node {
  int LT, RT, LB, RB;
  int val;
  node() {
    LT = RT = LB = RB = -1;
    val = 0;
  }
  node(int a, int b, int c, int d, int e) {
    LT = a;
    RT = b;
    LB = c;
    RB = d;
    val = e;
  }
};
node pool[8000000];
int ind;
int Ret;
int nowret = 0;
int query(int a, int b, int c, int d, int e, int f, int g, int h, int t) {
  if (d < a || b < c)
    return 0;
  if (h < e || f < g)
    return 0;
  if (c <= a && b <= d && g <= e && f <= h)
    return pool[t].val;
  if (nowret > pool[t].val)
    return 0;
  int ret = 0;
  if (~pool[t].LT) {
    ret = nowret =
        max(ret, query(a, (a + b) / 2, c, d, e, (e + f) / 2, g, h, pool[t].LT));
  }
  if (~pool[t].RT) {
    ret = nowret = max(
        ret, query(a, (a + b) / 2, c, d, (e + f) / 2 + 1, f, g, h, pool[t].RT));
  }
  if (~pool[t].LB) {
    ret = nowret = max(
        ret, query((a + b) / 2 + 1, b, c, d, e, (e + f) / 2, g, h, pool[t].LB));
  }
  if (~pool[t].RB) {
    ret = nowret = max(ret, query((a + b) / 2 + 1, b, c, d, (e + f) / 2 + 1, f,
                                  g, h, pool[t].RB));
  }
  return ret;
}
inline void update(int row, int col, int C) {
  int now = 0;
  int a = 0;
  int b = 1048575;
  int c = 0;
  int d = 1048575;
  while (1) {
    pool[now].val = max(pool[now].val, C);
    if (a == b)
      break;
    int M = (a + b) / 2;
    int N = (c + d) / 2;
    if (row <= M && col <= N) { // LT
      b = M;
      d = N;
      if (~pool[now].LT) {
        now = pool[now].LT;
      } else {
        pool[ind] = node();
        pool[now].LT = ind;
        now = ind++;
      }
    }
    if (row <= M && col > N) { // RT
      b = M;
      c = N + 1;
      if (~pool[now].RT) {
        now = pool[now].RT;
      } else {
        pool[ind] = node();
        pool[now].RT = ind;
        now = ind++;
      }
    }
    if (row > M && col <= N) { // LB
      a = M + 1;
      d = N;
      if (~pool[now].LB) {
        now = pool[now].LB;
      } else {
        pool[ind] = node();
        pool[now].LB = ind;
        now = ind++;
      }
    }
    if (row > M && col > N) { // RB
      a = M + 1;
      c = N + 1;
      if (~pool[now].RB) {
        now = pool[now].RB;
      } else {
        pool[ind] = node();
        pool[now].RB = ind;
        now = ind++;
      }
    }
  }
}
pair<int, pair<int, int>> dat[400000];
int x[400000];
int y[400000];
int z[400000];
int Q[400000];
int wolfa, wolfb, wolfC = ~(1 << 31), wolfM = (1 << 16) - 1;
int r() {
  wolfa = 36969 * (wolfa & wolfM) + (wolfa >> 16);
  wolfb = 18000 * (wolfb & wolfM) + (wolfb >> 16);
  return (wolfC & ((wolfa << 16) + wolfb)) % 1000000;
}
int main() {
  int a, b, c, d;
  while (scanf("%d%d%d%d", &a, &b, &c, &d), a + b) {
    for (int i = 0; i < a; i++) {
      scanf("%d%d%d", x + i, y + i, z + i);
      dat[i] = make_pair(x[i], make_pair(-y[i], -z[i]));
    }
    wolfa = c;
    wolfb = d;
    for (int i = 0; i < b; i++) {
      int X = r();
      int Y = r();
      int Z = r();
      dat[i + a] = make_pair(X, make_pair(-Y, -Z));
    }
    int n = a + b;
    std::sort(dat, dat + n);
    pool[0] = node();
    ind = 1;
    Ret = 0;
    for (int i = 0; i < n; i++) {
      nowret = 0;
      int P = max(nowret, query(0, 1048575, 0, -dat[i].second.first - 1, 0,
                                1048575, 0, -dat[i].second.second - 1, 0)) +
              1;
      Ret = max(Ret, P);
      Q[i] = P;
      update(-dat[i].second.first, -dat[i].second.second, P);
    }
    printf("%d\n", Ret);
  }
}

Fixed submission:
#include <algorithm>
#include <stdio.h>
using namespace std;
struct node {
  int LT, RT, LB, RB;
  int val;
  node() {
    LT = RT = LB = RB = -1;
    val = 0;
  }
  node(int a, int b, int c, int d, int e) {
    LT = a;
    RT = b;
    LB = c;
    RB = d;
    val = e;
  }
};
node pool[8000000];
int ind;
int Ret;
int nowret = 0;
int query(int a, int b, int c, int d, int e, int f, int g, int h, int t) {
  if (d < a || b < c)
    return 0;
  if (h < e || f < g)
    return 0;
  if (c <= a && b <= d && g <= e && f <= h)
    return pool[t].val;
  if (nowret >= pool[t].val)
    return 0;
  int ret = 0;
  if (~pool[t].LT) {
    ret = nowret =
        max(ret, query(a, (a + b) / 2, c, d, e, (e + f) / 2, g, h, pool[t].LT));
  }
  if (~pool[t].RT) {
    ret = nowret = max(
        ret, query(a, (a + b) / 2, c, d, (e + f) / 2 + 1, f, g, h, pool[t].RT));
  }
  if (~pool[t].LB) {
    ret = nowret = max(
        ret, query((a + b) / 2 + 1, b, c, d, e, (e + f) / 2, g, h, pool[t].LB));
  }
  if (~pool[t].RB) {
    ret = nowret = max(ret, query((a + b) / 2 + 1, b, c, d, (e + f) / 2 + 1, f,
                                  g, h, pool[t].RB));
  }
  return ret;
}
inline void update(int row, int col, int C) {
  int now = 0;
  int a = 0;
  int b = 1048575;
  int c = 0;
  int d = 1048575;
  while (1) {
    pool[now].val = max(pool[now].val, C);
    if (a == b)
      break;
    int M = (a + b) / 2;
    int N = (c + d) / 2;
    if (row <= M && col <= N) { // LT
      b = M;
      d = N;
      if (~pool[now].LT) {
        now = pool[now].LT;
      } else {
        pool[ind] = node();
        pool[now].LT = ind;
        now = ind++;
      }
    }
    if (row <= M && col > N) { // RT
      b = M;
      c = N + 1;
      if (~pool[now].RT) {
        now = pool[now].RT;
      } else {
        pool[ind] = node();
        pool[now].RT = ind;
        now = ind++;
      }
    }
    if (row > M && col <= N) { // LB
      a = M + 1;
      d = N;
      if (~pool[now].LB) {
        now = pool[now].LB;
      } else {
        pool[ind] = node();
        pool[now].LB = ind;
        now = ind++;
      }
    }
    if (row > M && col > N) { // RB
      a = M + 1;
      c = N + 1;
      if (~pool[now].RB) {
        now = pool[now].RB;
      } else {
        pool[ind] = node();
        pool[now].RB = ind;
        now = ind++;
      }
    }
  }
}
pair<int, pair<int, int>> dat[400000];
int x[400000];
int y[400000];
int z[400000];
int Q[400000];
int wolfa, wolfb, wolfC = ~(1 << 31), wolfM = (1 << 16) - 1;
int r() {
  wolfa = 36969 * (wolfa & wolfM) + (wolfa >> 16);
  wolfb = 18000 * (wolfb & wolfM) + (wolfb >> 16);
  return (wolfC & ((wolfa << 16) + wolfb)) % 1000000;
}
int main() {
  int a, b, c, d;
  while (scanf("%d%d%d%d", &a, &b, &c, &d), a + b) {
    for (int i = 0; i < a; i++) {
      scanf("%d%d%d", x + i, y + i, z + i);
      dat[i] = make_pair(x[i], make_pair(-y[i], -z[i]));
    }
    wolfa = c;
    wolfb = d;
    for (int i = 0; i < b; i++) {
      int X = r();
      int Y = r();
      int Z = r();
      dat[i + a] = make_pair(X, make_pair(-Y, -Z));
    }
    int n = a + b;
    std::sort(dat, dat + n);
    pool[0] = node();
    ind = 1;
    Ret = 0;
    for (int i = 0; i < n; i++) {
      nowret = 0;
      int P = max(nowret, query(0, 1048575, 0, -dat[i].second.first - 1, 0,
                                1048575, 0, -dat[i].second.second - 1, 0)) +
              1;
      Ret = max(Ret, P);
      Q[i] = P;
      update(-dat[i].second.first, -dat[i].second.second, P);
    }
    printf("%d\n", Ret);
  }
}