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

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

class SegmentTree {
private:
  vector<int> tree;
  const int INF = 99999999;
  int size;
  int init(int i) {
    if (i * 2 + 1 < tree.size())
      tree[i] = init(i * 2 + 1);
    if (i * 2 + 2 < tree.size())
      tree[i] = min(init(i * 2 + 2), tree[i]);
    return tree[i];
  }
  int get(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return tree[k];
    int vl = get(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = get(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);
  }

public:
  SegmentTree(vector<int> &v) {
    size = 1;
    while (size < v.size())
      size *= 2;
    tree.resize(size * 2 - 1);
    fill(tree.begin(), tree.end(), INF);
    for (int i = 0; i < v.size(); i++)
      tree[size - 1 + i] = v[i];
    init(0);
  }
  int get(int begin, int end) { return get(begin, end, 0, 0, size); }
};
class GreaterSegmentTree {
private:
  vector<int> tree;
  const int INF = -99999999;
  int size;
  int init(int i) {
    if (i * 2 + 1 < tree.size())
      tree[i] = init(i * 2 + 1);
    if (i * 2 + 2 < tree.size())
      tree[i] = max(init(i * 2 + 2), tree[i]);
    return tree[i];
  }
  int get(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return tree[k];
    int vl = get(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = get(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }

public:
  GreaterSegmentTree(vector<int> &v) {
    size = 1;
    while (size < v.size())
      size *= 2;
    tree.resize(size * 2 - 1);
    fill(tree.begin(), tree.end(), INF);
    for (int i = 0; i < v.size(); i++)
      tree[size - 1 + i] = v[i];
    init(0);
  }
  int get(int begin, int end) { return get(begin, end, 0, 0, size); }
};

class Star {
public:
  long long int x, y;
  int b;
  int boundary;
};
bool operator>(Star s1, Star s2) { return s1.b > s2.b; }
bool operator<(Star s1, Star s2) { return s1.b < s2.b; }

int n, d;
Star star[200000];
long long int ans = 0;

void calcBoundary() {
  int boundary = n - 1;
  star[n - 1].boundary = boundary;
  for (int i = n - 2; i >= 0; i--) {
    if (star[i + 1].b - star[i].b > d)
      boundary = i;
    star[i].boundary = boundary;
  }

  for (int i = 0; i < n; i++) {
    Star s;
    s.b = star[i].b + d;
    boundary = upper_bound(star + i, star + n, s) - star - 1;
    star[i].boundary = min(star[i].boundary, boundary);
  }
}

void solve() {
  vector<int> vx;
  vector<int> vy;
  for (int i = 0; i < n; i++) {
    vx.push_back(star[i].x);
    vy.push_back(star[i].y);
  }
  SegmentTree segX(vx), segY(vy);
  GreaterSegmentTree gsegX(vx), gsegY(vy);

  int boundary = star[n - 1].boundary;

  for (int i = n - 2; i >= 0; i--) {
    if (boundary != star[i].boundary) {
      long long int a = ((long long int)gsegX.get(i + 1, boundary + 1) -
                         (long long int)segX.get(i + 1, boundary + 1)) *
                        ((long long int)gsegY.get(i + 1, boundary + 1) -
                         (long long int)segY.get(i + 1, boundary + 1));
      ans = max(a, ans);
      boundary = star[i].boundary;
    }
  }
  long long int a = ((long long int)gsegX.get(0, boundary + 1) -
                     (long long int)segX.get(0, boundary + 1)) *
                    ((long long int)gsegY.get(0, boundary + 1) -
                     (long long int)segY.get(0, boundary + 1));
  ans = max(a, ans);
}

int main() {
  cin >> n >> d;
  for (int i = 0; i < n; i++)
    cin >> star[i].x >> star[i].y >> star[i].b;

  sort(star, star + n);
  calcBoundary();
  solve();

  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

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

class Star {
public:
  long long int x, y;
  int b;
  int boundary;
};
bool operator>(Star s1, Star s2) { return s1.b > s2.b; }
bool operator<(Star s1, Star s2) { return s1.b < s2.b; }

int n, d;
Star star[200000];
long long int maxX = 0, maxY = 0, minX = 0, minY = 0;
long long int ans = 0;

void calcBoundary() {
  int boundary = n - 1;
  star[n - 1].boundary = boundary;
  for (int i = n - 2; i >= 0; i--) {
    if (star[i + 1].b - star[i].b > d)
      boundary = i;
    star[i].boundary = boundary;
  }

  for (int i = 0; i < n; i++) {
    Star s;
    s.b = star[i].b + d;
    boundary = upper_bound(star + i, star + n, s) - star - 1;
    star[i].boundary = min(star[i].boundary, boundary);
  }
}

void solve() {
  int boundary = -1;
  for (int i = n - 1; i >= 0; i--) {
    if (star[i].boundary != boundary) {
      boundary = star[i].boundary;
      ans = max((minX - maxX) * (minY - maxY), ans);
      maxX = star[i].x;
      minX = star[i].x;
      maxY = star[i].y;
      minY = star[i].y;

      for (int j = i + 1; j <= star[i].boundary; j++) {
        maxX = max(star[j].x, maxX);
        maxY = max(star[j].y, maxY);
        minX = min(star[j].x, minX);
        minY = min(star[j].y, minY);
      }
    } else {
      maxX = max(star[i].x, maxX);
      maxY = max(star[i].y, maxY);
      minX = min(star[i].x, minX);
      minY = min(star[i].y, minY);
    }
  }

  ans = max((maxX - minX) * (maxY - minY), ans);
}

int main() {
  cin >> n >> d;
  for (int i = 0; i < n; i++)
    cin >> star[i].x >> star[i].y >> star[i].b;

  sort(star, star + n);
  calcBoundary();
  solve();

  cout << ans << endl;

  return 0;
}