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

#include <algorithm>
#include <cstdio>
#include <cstring>
using std::fill;
using std::lower_bound;
using std::max;
using std::sort;
using std::unique;
const int N = 330010;
struct point {
  int x, y, z;
  int id;
  bool operator<(const point &b) const {
    if (x == b.x) {
      if (y == b.y)
        return z > b.z;
      else
        return y > b.y;
    }
    return x < b.x;
  }
  inline void in() { scanf("%d%d%d", &x, &y, &z); }
} p[N], g[N];
int num[N];
int f[N];
inline int cmpy(point a, point b) { return a.y < b.y; }
struct BIT {
  int n;
  int c[N];
  inline void init(int n) { this->n = n; }
  inline void insert(int x, int add) {
    for (; x <= n; x += x & -x)
      if (add > c[x])
        c[x] = add;
  }
  inline int ask(int x) {
    int ret = 0;
    for (; x > 0; x -= x & -x)
      if (c[x] > ret)
        ret = c[x];
    return ret;
  }
  inline void clear(int x) {
    for (; x <= n; x += x & -x)
      c[x] = 0;
  }
} ta;
void update(int l1, int r1, int l2, int r2) {
  sort(g + l1, g + r1 + 1, cmpy);
  sort(g + l2, g + r2 + 1, cmpy);
  int pt = l1;
  for (int i = l2; i <= r2; i++) {
    while (pt <= r1 && g[pt].y < g[i].y) {
      ta.insert(g[pt].z, f[g[pt].id]);
      pt++;
    }
    int opt = ta.ask(g[i].z - 1);
    if (opt + 1 > f[g[i].id]) {
      f[g[i].id] = opt + 1;
    }
  }
  for (int i = l1; i <= r1; i++)
    ta.clear(g[i].z);
}
void solve(int l, int r) {
  if (l == r) {
    if (1 > f[p[l].id])
      f[p[l].id] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  solve(l, mid);
  for (int i = l; i <= r; i++)
    g[i] = p[i];
  if (p[mid].x != p[mid + 1].x) {
    // 蟾ヲ蜿ウ蛹コ髣エ驛ス謖臥?y謗貞コ?蟾ヲ蛹コ髣エ逧з蟾イ扈丈ソ晁ッ∝ー丈コ主承蛹コ髣エ逧з莠?
    update(l, mid, mid + 1, r);
  } else {
    int leftp = mid;
    while (leftp >= l && p[leftp].x == p[mid].x)
      leftp--;
    int rightp = mid + 1;
    while (rightp <= r && p[rightp].x == p[mid].x)
      rightp++;
    if (leftp < l && rightp > r) {
    } else if (leftp < l) {
      update(l, mid, rightp, r);
    } else if (rightp > r) {
      update(l, leftp, mid + 1, r);
    } else {
      update(l, leftp, mid + 1, r);
      for (int i = l; i <= r; i++)
        g[i] = p[i];
      update(leftp + 1, mid, rightp, r);
    }
  }
  solve(mid + 1, r);
}

int M, a, b, C;
int main() {
  int t, m, nn, A, B;
  while (scanf("%d%d%d%d", &m, &nn, &A, &B) && (m + nn + A + B)) {
    a = A;
    b = B;
    C = ~(1 << 31);
    M = (1 << 16) - 1;
    for (int i = 1; i <= m; i++) {
      p[i].in();
      p[i].id = i;
      num[i] = p[i].z;
    }
    for (int i = m + 1; i <= m + nn; i++) {
      a = 36969 * (a & M) + (a >> 16);
      b = 18000 * (b & M) + (b >> 16);
      int x = (C & ((a << 16) + b)) % 1000000;
      a = 36969 * (a & M) + (a >> 16);
      b = 18000 * (b & M) + (b >> 16);
      int y = (C & ((a << 16) + b)) % 1000000;
      a = 36969 * (a & M) + (a >> 16);
      b = 18000 * (b & M) + (b >> 16);
      int z = (C & ((a << 16) + b)) % 1000000;
      p[i].x = x;
      p[i].y = y;
      p[i].z = z;
      p[i].id = i;
      num[i] = p[i].z;
    }
    int n = m + nn;
    sort(num + 1, num + n + 1);
    int tot = unique(num + 1, num + n + 1) - num - 1;
    for (int i = 1; i <= n; i++)
      p[i].z = lower_bound(num + 1, num + tot + 1, p[i].z) - num;
    ta.init(n);
    sort(p + 1, p + n + 1);
    fill(f, f + n + 1, 1);
    solve(1, n);
    int ret = 1;
    for (int i = 1; i <= n; i++)
      ret = max(ret, f[i]);
    printf("%d\\n", ret);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <stdio.h>
#include <vector>

using namespace std;

struct P3 {
  int x, y, z;
  bool operator<(const P3 &p) const { return x < p.x; }

  P3() {}

  P3(int x, int y, int z) : x(x), y(y), z(z) {}
} p[300005];
int n, m, A, B;
int a, b, C = ~(1 << 31), M = (1 << 16) - 1;

int r() {
  a = 36969 * (a & M) + (a >> 16);
  b = 18000 * (b & M) + (b >> 16);
  return (C & ((a << 16) + b)) % 1000000;
}

int mx[300005];
int x[300005];

struct Node {
  Node *ch[2];
  int r, v, sz, w, mx;
  bool operator<(const Node &nd) const { return r < nd.r; }
  int cmp(int x) {
    if (x == v)
      return -1;
    return x > v;
  }
  void init(int w, int vv) {
    v = vv;
    this->w = w;
    mx = w;
    sz = 1;
    ch[0] = ch[1] = NULL;
    r = rand();
  }
} nd[10000005], *mp[300005];
int ndcnt = 0;
Node *newNode(int w, int v) {
  nd[ndcnt].init(w, v);
  return &nd[ndcnt++];
}

class Treap {
public:
  Treap() {}

  void push_Up(Node *rt) {
    if (rt == NULL)
      return;
    rt->sz = 1;
    rt->mx = rt->w;
    if (rt->ch[0] != NULL)
      rt->sz += rt->ch[0]->sz, rt->mx = max(rt->mx, rt->ch[0]->mx);
    if (rt->ch[1] != NULL)
      rt->sz += rt->ch[1]->sz, rt->mx = max(rt->mx, rt->ch[1]->mx);
  }

  void rotate(Node *&o, int d) {
    Node *k = o->ch[d ^ 1];
    o->ch[d ^ 1] = k->ch[d];
    k->ch[d] = o;
    push_Up(o);
    push_Up(k);
    o = k;
  }

  void insert(Node *&o, int w, int x) {
    if (o == NULL)
      o = newNode(w, x);
    else {
      int d = (x < o->v ? 0 : 1);
      insert(o->ch[d], w, x);
      if (o->ch[d] > o)
        rotate(o, d ^ 1);
    }
    push_Up(o);
  }

  int query(Node *o, int val) {
    if (o == NULL)
      return 0;
    int ans = 0;
    if (o->v < val) {
      if (o->ch[0] != NULL)
        ans = o->ch[0]->mx;
      ans = max(ans, o->w);
      ans = max(ans, query(o->ch[1], val));
    } else
      ans = max(ans, query(o->ch[0], val));
    return ans;
  }
} treap;

#define lowbit(u) (u & (-u))

struct BIT {
  int n;
  BIT(int n) {
    this->n = n;
    for (int i = 1; i <= n; i++)
      mp[i] = newNode(0, 0);
  }

  void add(int u, int v, int y) {
    for (int i = u; i <= n; i += lowbit(i))
      treap.insert(mp[i], v, y);
  }

  int sum(int u, int y) {
    int ans = 0;
    for (int i = u; i; i -= lowbit(i))
      ans = max(ans, treap.query(mp[i], y));
    return ans;
  }
};

P3 buffer[300005];

void getInt(int &x) {
  x = 0;
  char c = getchar();
  while (c == ' ' || c == '\\n')
    c = getchar();
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
}

int main() {
  // freopen("data.in","r",stdin);
  srand(time(NULL));
  while (scanf("%d %d %d %d", &n, &m, &A, &B), n + m + A + B) {
    a = A, b = B;
    for (int i = 0; i < n; i++) {
      scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z);
    }
    for (int i = 0; i < m; i++)
      p[i + n].x = r();
    for (int i = 0; i < m; i++)
      p[i + n].y = r();
    for (int i = 0; i < m; i++)
      p[i + n].z = r();
    n += m;
    int cnt = 0;
    for (int i = 0; i < n; i++)
      x[cnt++] = p[i].y;
    sort(x, x + cnt);
    cnt = unique(x, x + cnt) - x;
    for (int i = 0; i < n; i++)
      p[i].y = lower_bound(x, x + cnt, p[i].y) - x + 1;
    sort(p, p + n);
    ndcnt = 0;
    BIT bit(cnt + 1);
    int tot = 0;
    int ans = 0;
    for (int i = 0; i < n; i++) {
      int ret = 0;
      ret = bit.sum(p[i].y - 1, p[i].z) + 1;
      ans = max(ans, ret);
      buffer[tot++] = P3(p[i].y, ret, p[i].z);
      if (i < n - 1 && p[i].x != p[i + 1].x) {
        int sz = tot;
        for (int j = 0; j < sz; j++) {
          bit.add(buffer[j].x, buffer[j].y, buffer[j].z);
        }
        tot = 0;
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}