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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef pair<int, P> Pint;
typedef pair<P, P> PP;
int a, b, C, M;
int r() {
  a = 36969 * (a & M) + (a >> 16);
  b = 18000 * (b & M) + (b >> 16);
  return (C & ((a << 16) + b)) % 1000000;
}
const int MAX_N = 1 << 19;
int m0;
vector<P> v1[2 * MAX_N - 1];
vector<int> v[2 * MAX_N - 1];
vector<Pint> p;
int ct;
void init() {
  for (int i = 1; i <= ct; i++) {
    v[i].clear();
    v1[i].clear();
    vector<int>().swap(v[i]);
    vector<P>().swap(v1[i]);
  }
  for (int i = 0; i < p.size(); i++) {
    int x = p[i].first, y = p[i].second.first, z = p[i].second.second;
    int i0 = y;
    while (i0 <= ct) {
      v1[i0].push_back(P(z, i));
      i0 += (i0 & (-i0));
    }
  }
  for (int i = 1; i <= ct; i++) {
    if (v1[i].empty())
      continue;
    sort(v1[i].begin(), v1[i].end());
    for (int j = 0; j <= v1[i].size(); j++) {
      v[i].push_back(0);
    }
  }
}

void update(int k, int i, int a) {
  while (i <= v1[k].size()) {
    v[k][i] = max(v[k][i], a);
    i += (i & (-i));
  }
}

void update0(int i, int y, int z, int a) {
  int k = y;
  while (k <= ct) {
    int i0 = lower_bound(v1[k].begin(), v1[k].end(), P(z, i)) - v1[k].begin();
    update(k, i0 + 1, a);
    k += (k & (-k));
  }
}

int find(int k, int i) {
  int s = 0;
  while (i > 0) {
    s = max(s, v[k][i]);
    i -= (i & (-i));
  }
  return s;
}

int find0(int y, int z) {
  int s = 0;
  int k = y - 1;
  while (k > 0) {
    if (!v1[k].empty()) {
      int i = lower_bound(v1[k].begin(), v1[k].end(), P(z, -1)) - v1[k].begin();
      if (i != 0)
        s = max(s, find(k, i));
    }
    k -= (k & (-k));
  }
  return s;
}

int main() {
  while (1) {
    int m, n, A, B;
    scanf("%d %d %d %d", &m, &n, &A, &B);
    if (m == 0 && n == 0 && A == 0 && B == 0)
      return 0;
    a = A, b = B, C = ~(1 << 31), M = (1 << 16) - 1;
    for (int i = 0; i < m; i++) {
      int x, y, z;
      cin >> x >> y >> z;
      p.push_back(Pint(x, P(y, z)));
    }
    for (int i = 0; i < n; i++) {
      int x = r();
      int y = r();
      int z = r();
      p.push_back(Pint(x, P(y, z)));
    }
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    int ind[300000];
    for (int i = 0; i < p.size(); i++)
      ind[i] = i;
    sort(ind, ind + p.size(),
         [&](int x, int y) { return p[x].second.first < p[y].second.first; });
    int pr = -1;
    ct = 0;
    for (int i = 0; i < p.size(); i++) {
      if (pr != p[ind[i]].second.first) {
        pr = p[ind[i]].second.first;
        ct++;
        p[ind[i]].second.first = ct;
      } else {
        p[ind[i]].second.first = ct;
      }
    }
    init();
    vector<PP> mxv;
    int xp = -1;
    for (int i = 0; i < p.size(); i++) {
      int x = p[i].first, y = p[i].second.first, z = p[i].second.second;
      if (xp == x) {
        mxv.push_back(PP(P(i, y), P(z, find0(y, z))));
      } else {
        for (auto t : mxv) {
          update0(t.first.first, t.first.second, t.second.first,
                  t.second.second + 1);
        }
        mxv.clear();
        xp = x;
        mxv.push_back(PP(P(i, y), P(z, find0(y, z))));
      }
    }
    for (auto t : mxv) {
      update0(t.first.first, t.first.second, t.second.first,
              t.second.second + 1);
    }
    printf("%d\\n", find0(ct + 1, 1000000));
    p.clear();
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef pair<int, P> Pint;
typedef pair<P, P> PP;
int a, b, C, M;
int r() {
  a = 36969 * (a & M) + (a >> 16);
  b = 18000 * (b & M) + (b >> 16);
  return (C & ((a << 16) + b)) % 1000000;
}
const int MAX_N = 1 << 19;
int m0;
vector<P> v1[2 * MAX_N - 1];
vector<int> v[2 * MAX_N - 1];
vector<Pint> p;

void init(int m_) {
  m0 = 1;
  while (m0 < m_)
    m0 *= 2;
  for (int i = 0; i < 2 * m0 - 1; i++) {
    v[i].clear();
    v1[i].clear();
    vector<int>().swap(v[i]);
    vector<P>().swap(v1[i]);
  }
  for (int i = 0; i < p.size(); i++) {
    int x = p[i].first, y = p[i].second.first, z = p[i].second.second;
    int i0 = y + m0 - 1;
    v1[i0].push_back(P(z, i));
    while (i0 > 0) {
      i0 = (i0 - 1) / 2;
      v1[i0].push_back(P(z, i));
    }
  }
  for (int i = 0; i < 2 * m0 - 1; i++) {
    if (v1[i].empty())
      continue;
    sort(v1[i].begin(), v1[i].end());
    for (int j = 0; j <= v1[i].size(); j++) {
      v[i].push_back(0);
    }
  }
}

void update(int k, int i, int a) {
  while (i <= v[k].size()) {
    v[k][i] = max(v[k][i], a);
    i += (i & (-i));
  }
}

void update0(int i, int y, int z, int a, int k, int l, int r) {
  if (r <= y || y + 1 <= l)
    return;
  int i0 = lower_bound(v1[k].begin(), v1[k].end(), P(z, i)) - v1[k].begin();
  if (i0 < v1[k].size()) {
    update(k, i0 + 1, a);
  }
  if (r - l > 1) {
    if (l <= y && y < (l + r) / 2) {
      update0(i, y, z, a, 2 * k + 1, l, (l + r) / 2);
    } else {
      update0(i, y, z, a, 2 * k + 2, (l + r) / 2, r);
    }
  }
}

int find(int k, int i) {
  int s = 0;
  while (i > 0) {
    s = max(s, v[k][i]);
    i -= (i & (-i));
  }
  return s;
}

int find0(int y, int z, int k, int l, int r) {
  if (r <= 0 || y <= l)
    return 0;
  if (0 <= l && r <= y) {
    if (v1[k].empty())
      return 0;
    int i = lower_bound(v1[k].begin(), v1[k].end(), P(z, -1)) - v1[k].begin();
    if (i == 0)
      return 0;
    return find(k, i);
  } else {
    int vl = find0(y, z, k * 2 + 1, l, (l + r) / 2);
    int vr = find0(y, z, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int main() {
  while (1) {
    int m, n, A, B;
    scanf("%d %d %d %d", &m, &n, &A, &B);
    if (m == 0 && n == 0 && A == 0 && B == 0)
      return 0;
    a = A, b = B, C = ~(1 << 31), M = (1 << 16) - 1;
    for (int i = 0; i < m; i++) {
      int x, y, z;
      cin >> x >> y >> z;
      p.push_back(Pint(x, P(y, z)));
    }
    for (int i = 0; i < n; i++) {
      int x = r();
      int y = r();
      int z = r();
      p.push_back(Pint(x, P(y, z)));
    }
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    int ind[300000];
    for (int i = 0; i < p.size(); i++)
      ind[i] = i;
    sort(ind, ind + p.size(),
         [&](int x, int y) { return p[x].second.first < p[y].second.first; });
    int ct = -1, pr = -1;
    for (int i = 0; i < p.size(); i++) {
      if (pr != p[ind[i]].second.first) {
        pr = p[ind[i]].second.first;
        ct++;
        p[ind[i]].second.first = ct;
      } else {
        p[ind[i]].second.first = ct;
      }
    }
    init(ct + 1);
    vector<PP> mxv;
    int xp = -1;
    for (int i = 0; i < p.size(); i++) {
      int x = p[i].first, y = p[i].second.first, z = p[i].second.second;
      if (xp == x) {
        mxv.push_back(PP(P(i, y), P(z, find0(y, z, 0, 0, m0))));
      } else {
        for (auto t : mxv) {
          update0(t.first.first, t.first.second, t.second.first,
                  t.second.second + 1, 0, 0, m0);
        }
        mxv.clear();
        xp = x;
        mxv.push_back(PP(P(i, y), P(z, find0(y, z, 0, 0, m0))));
      }
    }
    for (auto t : mxv) {
      update0(t.first.first, t.first.second, t.second.first,
              t.second.second + 1, 0, 0, m0);
    }
    printf("%d\\n", find0(ct + 1, 1000000, 0, 0, m0));
    p.clear();
  }
  return 0;
}