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

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
const int MAXN = 300000 + 10, inf = 1e9;

struct Node {
  PII e;
  Node *ls, *rs;
  int dim, cur, sub;
} pool[MAXN], *cnt;

struct Point {
  int x, y, z;
  Point() {}
  Point(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
  bool operator<(const Point &rhs) const {
    return x < rhs.x || (x == rhs.x && y < rhs.y) ||
           (x == rhs.x && y == rhs.y && z < rhs.z);
  }
} P[MAXN];

map<int, int> best[MAXN];
int dp[MAXN], ret;

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

inline bool check(const map<int, int> &mp, int x, int y) {
  auto it = mp.lower_bound(x);
  return it != mp.begin() && (--it)->second < y;
}

int query(int x, int y) {
  int left = 0, right = ret;
  while (left < right) {
    int mid = (left + right + 1) >> 1;
    if (check(best[mid], x, y))
      left = mid;
    else
      right = mid - 1;
  }
  return left;
}

void update(map<int, int> &mp, int x, int y) {
  auto it = mp.upper_bound(x);
  if (it != mp.begin() && (--it)->second <= y)
    return;
  it = mp.lower_bound(x);
  while (it != mp.end() && it->second >= y)
    mp.erase(it++);
  mp[x] = y;
}

int main() {
  int N, M, A, B;
  while (scanf("%d%d%d%d", &M, &N, &A, &B) == 4 && (N + M)) {
    for (int i = 0; i < M; ++i) {
      scanf("%d%d%d", &P[i].x, &P[i].y, &P[i].z);
    }
    N += M;
    for (int i = M; i < N; ++i) {
      P[i].x = r(A, B);
      P[i].y = r(A, B);
      P[i].z = r(A, B);
    }
    for (int i = 0; i <= N; ++i)
      best[i].clear();
    sort(P, P + N);
    ret = 0;
    for (int i = 0, j; i < N;) {
      for (j = i; j < N && P[i].x == P[j].x; ++j)
        dp[j] = query(P[j].y, P[j].z) + 1;
      for (; i < j; ++i) {
        update(best[dp[i]], P[i].y, P[i].z);
        ret = max(ret, dp[i]);
      }
    }
    printf("%d\\n", ret);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
const int MAXN = 300000 + 10, inf = 1e9;

struct Node {
  PII e;
  Node *ls, *rs;
  int dim, cur, sub;
} pool[MAXN], *cnt;

struct Point {
  int x, y, z;
  Point() {}
  Point(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
  bool operator<(const Point &rhs) const {
    return x < rhs.x || (x == rhs.x && y < rhs.y) ||
           (x == rhs.x && y == rhs.y && z < rhs.z);
  }
} Triple[MAXN];

PII P[MAXN];
int N, M, A, B;

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

inline bool cmpX(const PII &a, const PII &b) {
  return a.first < b.first || (a.first == b.first && a.second < b.second);
}

inline bool cmpY(const PII &a, const PII &b) {
  return a.second < b.second || (a.second == b.second && a.first < b.first);
}

Node *build(PII P[], int l, int r, int dim) {
  if (l >= r)
    return NULL;
  Node *rt = cnt++;
  rt->dim = dim;
  int mid = (l + r) >> 1;
  nth_element(P + l, P + mid, P + r, dim ? cmpY : cmpX);
  rt->e = P[mid];
  rt->cur = rt->sub = 0;
  rt->ls = build(P, l, mid, dim ^ 1);
  ;
  rt->rs = build(P, mid + 1, r, dim ^ 1);
  return rt;
}

void modify(Node *rt, const PII &e, int value) {
  rt->sub = max(rt->sub, value);
  if (e == rt->e) {
    rt->cur = max(rt->cur, value);
    return;
  }
  bool o = rt->dim ? cmpY(e, rt->e) : cmpX(e, rt->e);
  if (o)
    modify(rt->ls, e, value);
  else
    modify(rt->rs, e, value);
}

int ret;
void get(Node *rt, const PII &e, int maxx = inf, int maxy = inf) {
  if (!rt)
    return;
  if (maxx < e.first && maxy < e.second)
    ret = max(ret, rt->sub);
  else {
    if (rt->e.first < e.first && rt->e.second < e.second)
      ret = max(ret, rt->cur);
    if (rt->dim) {
      if (rt->e.second < e.second)
        get(rt->rs, e, maxx, maxy);
      get(rt->ls, e, maxx, min(maxy, rt->e.second));
    } else {
      if (rt->e.first < e.first)
        get(rt->rs, e, maxx, maxy);
      get(rt->ls, e, min(maxx, rt->e.first), maxy);
    }
  }
}

int main() {
  while (scanf("%d%d%d%d", &M, &N, &A, &B) == 4 && (N + M)) {
    for (int i = 0; i < M; ++i) {
      scanf("%d%d%d", &Triple[i].x, &Triple[i].y, &Triple[i].z);
      P[i] = PII(Triple[i].y, Triple[i].z);
    }
    N += M;
    for (int i = M; i < N; ++i) {
      Triple[i].x = r();
      Triple[i].y = r();
      Triple[i].z = r();
      P[i] = PII(Triple[i].y, Triple[i].z);
    }
    sort(P, P + N);
    M = unique(P, P + N) - P;
    cnt = pool;
    Node *root = build(P, 0, M, 0);
    sort(Triple, Triple + N);
    for (int i = 0; i < N; ++i) {
      ret = 0;
      get(root, PII(Triple[i].y, Triple[i].z));
      modify(root, PII(Triple[i].y, Triple[i].z), ret + 1);
    }
    printf("%d\\n", root->sub);
  }
  return 0;
}