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

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 200000 + 10;
const int dem = 2;
const double INF = (1e200);

struct Point {
  double x[dem];
} p[maxn];

int n;
double minx[1 << dem], maxx[1 << dem];

double solve() {
  int tmp = 1 << dem;

  for (int i = 0; i < tmp; i++) {
    minx[i] = INF;
    maxx[i] = -INF;
  }

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < tmp; j++) {
      int t = j;
      double s = 0;
      for (int k = 0; k < dem; k++) {
        if (t & 1)
          s += p[i].x[k];
        else
          s -= p[i].x[k];
        t >>= 1;
      }
      if (maxx[j] < s)
        maxx[j] = s;
      if (minx[j] > s)
        minx[j] = s;
    }
  }

  double ans = -INF;
  for (int i = 0; i < tmp; i++) {
    if (maxx[i] - minx[i] > ans)
      ans = maxx[i] - minx[i];
  }

  return ans;
}

int main() {

  while (scanf("%d", &n) != EOF) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < dem; j++) {
        scanf("%lf", &p[i].x[j]);
      }
    }
    printf("%.0f\\n", solve());
  }

  return 0;
}

Error: TLE

Fixed submission:


// Problem : E - Dist Max
// Contest : AtCoder - AtCoder Beginner Contest 178
// URL : https://atcoder.jp/contests/abc178/tasks/abc178_e
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#pragma GCC optimize(2)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <set>
using std::make_pair;
using std::nth_element;
using std::pair;
using std::set;
const int k(2), N(2e5 + 5);
typedef double dbl;
const dbl inf(1e9);
template <class type> inline const type max(const type &a, const type &b) {
  return a > b ? a : b;
}
template <class type> inline const type min(const type &a, const type &b) {
  return a < b ? a : b;
}
bool f;
inline const dbl sqr(const dbl &x) { return x * x; }
struct point {
  dbl d[k];
  inline point() {}
  inline point(const dbl &x, const dbl &y) {
    d[0] = x;
    d[1] = y;
  }
  inline const bool operator<(const point &p) const {
    if (d[f] != p.d[f])
      return d[f] < p.d[f];
    for (int i(0); i < k; i++)
      if (d[i] != p.d[i])
        return d[i] < p.d[i];
    return 0;
  }
  inline const bool operator!=(const point &p) const {
    for (int i(0); i < k; i++)
      if (d[i] != p.d[i])
        return 1;
    return 0;
  }
  inline const friend dbl distance(const point &x, const point &y) {
    dbl dis(0);
    for (int i(0); i < k; i++)
      dis += abs(x.d[i] - y.d[i]);
    return dis;
  }
} a[N];
dbl ans_min(inf), ans_max;
struct tree {
  point range, mn, mx;
  tree *son[2];
  static tree *null;
  void *operator new(size_t size);
  inline tree() { son[0] = son[1] = null; }
  inline tree(const point &p) : range(p), mn(p), mx(p) {
    static bool init(0);
    if (!init)
      init = 1, null = new tree, null->son[0] = null->son[1] = null,
      null->mn.d[0] = null->mn.d[1] = inf;
    son[0] = son[1] = null;
  }
  inline const void pushup() {
    for (int i(0); i < k; i++)
      mx.d[i] = max(range.d[i], max(son[0]->mx.d[i], son[1]->mx.d[i])),
      mn.d[i] = min(range.d[i], min(son[0]->mn.d[i], son[1]->mn.d[i]));
  }
  inline const dbl evalue_min(const point &p) {
    if (this == null)
      return inf;
    dbl f(0);
    for (int i(0); i < k; i++)
      f += sqr(max(mn.d[i] - p.d[i], 0.0)) + sqr(max(p.d[i] - mx.d[i], 0.0));
    return f;
  }
  inline const dbl evalue_max(const point &p) {
    if (this == null)
      return 0;
    dbl f(0);
    for (int i(0); i < k; i++)
      f += max(sqr(mn.d[i] - p.d[i]), sqr(mx.d[i] - p.d[i]));
    return f;
  }
  inline const void query_min(const point &p) {
    if (this == null)
      return;
    if (p != range)
      ans_min = min(ans_min, distance(range, p));
    const dbl f[k] = {son[0]->evalue_min(p), son[1]->evalue_min(p)};
    const bool t(f[0] >= f[1]);
    if (f[t] < ans_min)
      son[t]->query_min(p);
    if (f[!t] < ans_min)
      son[!t]->query_min(p);
  }
  inline const void query_max(const point &p) {
    if (this == null)
      return;
    ans_max = max(ans_max, distance(range, p));
    const dbl f[k] = {son[0]->evalue_max(p), son[1]->evalue_max(p)};
    const bool t(f[0] <= f[1]);
    if (f[t] > ans_max)
      son[t]->query_max(p);
    if (f[!t] > ans_max)
      son[!t]->query_max(p);
  }
} *root, *tree::null;
#define null tree::null
char memory_pool[N * sizeof(tree)], *tail(memory_pool + sizeof memory_pool);
inline void *tree::operator new(size_t size) { return tail -= size; }
inline tree *build(const int &l, const int &r, const bool &d) {
  if (l > r)
    return null;
  const int mid(l + r >> 1);
  f = d;
  nth_element(a + l, a + mid, a + r + 1);
  tree *p(new tree(a[mid]));
  if (l == r)
    return p;
  p->son[0] = build(l, mid - 1, !d);
  p->son[1] = build(mid + 1, r, !d);
  p->pushup();
  return p;
}
set<point> s;
int n;
int main() {
  scanf("%d", &n);
  for (int i(1); i <= n; i++) {
    for (int j(0); j < k; j++)
      scanf("%lf", &a[i].d[j]);
    if (!s.insert(a[i]).second)
      ans_min = 0;
  }
  root = build(1, n, 0);
  if (ans_min)
    for (int i(1); i <= n; i++)
      root->query_min(a[i]);
  for (int i(1); i <= n; i++)
    root->query_max(a[i]);
  printf("%.0f\\n", ans_max);
  return 0;
}