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

#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;

int n;

struct tup {
  int x, y, z;
} a[300005];

map<int, int> mp[300005];
int dp[300005];

bool input() {
  int m, nn, A, B;
  scanf("%d %d %d %d", &m, &nn, &A, &B);
  if (m + nn + A + B == 0)
    return 0;
  n = m + nn;
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
  }
  int a = A, b = B, C = ~(1 << 31), M = (1 << 16) - 1;
  for (int i = m + 1; i <= n; i++) {
    a = 36969 * (a & M) + (a >> 16);
    b = 18000 * (b & M) + (b >> 16);
    ::a[i].x = (C & ((a << 16) + b)) % 1000000;
    a = 36969 * (a & M) + (a >> 16);
    b = 18000 * (b & M) + (b >> 16);
    ::a[i].y = (C & ((a << 16) + b)) % 1000000;
    a = 36969 * (a & M) + (a >> 16);
    b = 18000 * (b & M) + (b >> 16);
    ::a[i].z = (C & ((a << 16) + b)) % 1000000;
  }
  for (int i = 0; i <= n; i++) {
    mp[i].clear();
  }
  return 1;
}

bool trial(int m, int y, int z) {
  auto it = mp[m].lower_bound(y);
  if (it == mp[m].begin())
    return 0;
  it--;
  return (z > it->second);
}

void add(int x, int y, int z) {
  auto it = mp[x].lower_bound(y);
  auto it2 = mp[x].upper_bound(y);
  if (it2 != mp[x].begin()) {
    it2--;
    if (it2->second <= z)
      return;
  }
  while (it != mp[x].end() && it->second >= z) {
    mp[x].erase(it);
    it = mp[x].lower_bound(y);
  }
  mp[x].insert(make_pair(y, z));
}

void solve() {
  sort(a + 1, a + n + 1, [&](const tup &a, const tup &b) { return a.x < b.x; });
  mp[0].insert(make_pair(-1, -1));
  for (int i = 1; i <= n;) {
    int e = i;
    while (e <= n && a[e].x == a[i].x)
      e++;
    for (int j = i; j < e; j++) {
      int s = 0, e = i;
      while (s != e) {
        int m = (s + e + 1) / 2;
        if (trial(m, a[j].y, a[j].z))
          s = m;
        else
          e = m - 1;
      }
      dp[j] = s + 1;
    }
    for (int j = i; j < e; j++) {
      add(dp[j], a[j].y, a[j].z);
    }
    i = e;
  }
  printf("%d\\n", *max_element(dp + 1, dp + n + 1));
}

int main() {
  while (input()) {
    solve();
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <map>
#include <time.h>
#include <vector>
using namespace std;
typedef pair<int, int> pi;
typedef map<int, int>::iterator aauto;

int n;

struct tup {
  int x, y, z;
} a[300005];

time_t st;
bool input() {
  int pn, m, aa, b;
  scanf("%d %d %d %d", &pn, &m, &aa, &b);
  if (pn + m == 0)
    return 0;
  for (int i = 1; i <= pn; i++) {
    scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
  }
  n = pn;
  int M = 65535, C = ~(1 << 31);
  while (m--) {
    n++;
    aa = 36969 * (aa & M) + (aa >> 16);
    b = 18000 * (b & M) + (b >> 16);
    a[n].x = (C & ((aa << 16) + b)) % 1000000;
    aa = 36969 * (aa & M) + (aa >> 16);
    b = 18000 * (b & M) + (b >> 16);
    a[n].y = (C & ((aa << 16) + b)) % 1000000;
    aa = 36969 * (aa & M) + (aa >> 16);
    b = 18000 * (b & M) + (b >> 16);
    a[n].z = (C & ((aa << 16) + b)) % 1000000;
  }
  return 1;
}

vector<int> vy, vz;

struct idx {
  map<int, int> mp[1050000];
  int lim;
  void init(int n) {
    for (lim = 1; lim <= n; lim <<= 1)
      ;
    for (int i = 1; i <= lim + n; i++) {
      mp[i].clear();
    }
  }
  int qr(int x, int p) {
    aauto t = mp[x].upper_bound(p);
    if (t != mp[x].begin()) {
      return (--t)->second;
    }
    return 0;
  }
  void manip(int x, pi t) {
    aauto it = mp[x].upper_bound(t.first);
    if (it != mp[x].begin() && (--it)->second >= t.second) {
      return;
    }
    mp[x][t.first] = t.second;
    it = mp[x].upper_bound(t.first);
    while (it != mp[x].end()) {
      if (it->second <= t.second) {
        aauto bak = it;
        bak++;
        mp[x].erase(it);
        it = bak;
      } else
        break;
    }
  }
  void add(int x, int v, int w) {
    x += lim;
    manip(x, pi(v, w));
    while (x > 15) {
      x >>= 1;
      manip(x, pi(v, w));
    }
  }
  int q(int s, int e, int x) {
    s += lim;
    e += lim;
    int ret = 0;
    while (s < e && s > 15) {
      if (s % 2 == 1)
        ret = max(ret, qr(s++, x));
      if (e % 2 == 0)
        ret = max(ret, qr(e--, x));
      s >>= 1;
      e >>= 1;
    }
    for (int i = s; i <= e; i++) {
      ret = max(ret, qr(i, x));
    }
    return ret;
  }
} idx;

int dp[300005];

bool cmp(const tup &a, const tup &b) {
  if (a.x != b.x)
    return a.x < b.x;
  if (a.y != b.y)
    return a.y < b.y;
  return a.z < b.z;
}

void solve() {
  sort(a + 1, a + n + 1, cmp);
  vy.clear();
  vz.clear();
  for (int i = 1; i <= n; i++) {
    vy.push_back(a[i].y);
    vz.push_back(a[i].z);
  }
  sort(vy.begin(), vy.end());
  sort(vz.begin(), vz.end());
  vy.resize(unique(vy.begin(), vy.end()) - vy.begin());
  vz.resize(unique(vz.begin(), vz.end()) - vz.begin());
  for (int i = 1; i <= n; i++) {
    a[i].y = (int)(lower_bound(vy.begin(), vy.end(), a[i].y) - vy.begin());
    a[i].z = (int)(lower_bound(vz.begin(), vz.end(), a[i].z) - vz.begin());
  }
  idx.init(n);
  for (int i = 1; i <= n;) {
    int e = i;
    while (e <= n && a[e].x == a[i].x)
      e++;
    for (int j = i; j < e; j++) {
      dp[j] = idx.q(0, a[j].y - 1, a[j].z - 1) + 1;
    }
    for (int j = i; j < e; j++) {
      idx.add(a[j].y, a[j].z, dp[j]);
    }
    i = e;
  }
  printf("%d\\n", *max_element(dp + 1, dp + n + 1));
}

int main() {
  while (input()) {
    solve();
  }
}