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

#include <algorithm>
#include <vector>

using namespace std;

template <typename Type> class RMQ {
private:
  int size;

  vector<Type> maxvalue;

  Type _query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return INF;
    }
    if (a <= l && r <= b) {
      return maxvalue[k];
    }

    Type vl = _query(a, b, 2 * k, l, (l + r) / 2);
    Type vr = _query(a, b, 2 * k + 1, (l + r) / 2, r);

    return max(vl, vr);
  }

public:
  Type INF;

  RMQ(int size_) {
    INF = numeric_limits<Type>::min() / 2;

    for (size = 1; size < size_;) {
      size <<= 1;
    }

    maxvalue = vector<Type>(size * 2, INF);
  }

  void update(int i, const Type &x) {
    i += size;

    maxvalue[i] = x;

    while (i > 1) {
      i = i / 2;

      maxvalue[i] = max(maxvalue[2 * i], maxvalue[2 * i + 1]);
    }
  }

  Type query(int s, int t) { return _query(s, t, 1, 0, size); }
};

#include <cstdio>

int main() {
  int power[16];
  power[0] = 1;

  for (int i = 1; i < 16; i++) {
    power[i] = power[i - 1] * 3;
  }

  int N;
  long long D;

  scanf("%d", &N);
  scanf("%lld", &D);

  int mid = N / 2;

  int power1 = power[mid];
  int power2 = power[N - mid];

  vector<long long> X(N);
  vector<long long> Y(N);

  for (int i = 0; i < N; i++) {
    scanf("%lld", &X[i]);
    scanf("%lld", &Y[i]);
  }

  vector<long long> D1X, D1Y;

  vector<pair<long long, long long>> D2;

  long long X3, Y3;

  for (int i = 0; i < power1; i++) {
    X3 = 0LL;
    Y3 = 0LL;

    for (int j = 0; j < mid; j++) {
      switch ((i / power[j]) % 3) {
      case 0:
        X3 -= X[j];
        Y3 -= Y[j];
        break; // Anna
      case 1:
        X3 += X[j];
        Y3 += Y[j];
        break; // Bruno
      }
    }

    D1X.push_back(X3);
    D1Y.push_back(Y3);
  }

  for (int i = 0; i < power2; i++) {
    X3 = 0LL;
    Y3 = 0LL;

    for (int j = mid; j < N; j++) {
      switch ((i / power[j - mid]) % 3) {
      case 0:
        X3 -= X[j];
        Y3 -= Y[j];
        break; // Anna
      case 1:
        X3 += X[j];
        Y3 += Y[j];
        break; // Bruno
      }
    }

    D2.push_back(make_pair(X3, Y3));
  }

  sort(D2.begin(), D2.end(),
       [](pair<long long, long long> x, pair<long long, long long> y) {
         return x.first < y.first;
       });

  int D1_size = D1X.size();
  int D2_size = D2.size();

  vector<long long> X1;

  RMQ<long long> rmq(N != 30 ? D2_size : 0);

  if (N != 30) {
    for (int i = 0; i < D2_size; i++) {
      X1.push_back(D2[i].first);

      rmq.update(i, D2[i].second);
    }
  } else {
    for (int i = 0; i < D2_size; i++) {
      X1.push_back(D2[i].first);
    }
  }

  long long Ans = numeric_limits<long long>::min() / 2;

  int ptr1, ptr2;

  if (N != 30) {
    for (int i = 0; i < D1_size; i++) {
      long long _D1X = -D1X[i];

      ptr1 = distance(X1.begin(), lower_bound(X1.begin(), X1.end(), _D1X - D));
      ptr2 = distance(X1.begin(), upper_bound(X1.begin(), X1.end(), _D1X + D));

      if (ptr1 != ptr2) {
        Ans = max(D1Y[i] + rmq.query(ptr1, ptr2), Ans);
      }
    }
  } else {
    for (int i = 0; i < D1_size; i++) {
      long long _D1X = -D1X[i];

      ptr1 = distance(X1.begin(), lower_bound(X1.begin(), X1.end(), _D1X - D));
      ptr2 = distance(X1.begin(), upper_bound(X1.begin(), X1.end(), _D1X + D));

      for (int j = ptr1; j < ptr2; j++) {
        Ans = max(D1Y[i] + D2[j].second, Ans);
      }
    }
  }

  printf("%lld\\n", Ans);

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <vector>

using namespace std;

#define INF -(1LL << 60)

template <typename Type> class RMQ {
private:
  int size;

  vector<Type> maxvalue;

  Type _query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return INF;
    }
    if (a <= l && r <= b) {
      return maxvalue[k];
    }

    Type vl = _query(a, b, 2 * k + 1, l, (l + r) / 2);
    Type vr = _query(a, b, 2 * k + 2, (l + r) / 2, r);

    return max(vl, vr);
  }

public:
  RMQ(int size_) {
    for (size = 1; size < size_;) {
      size <<= 1;
    }

    maxvalue = vector<Type>(size * 2 - 1, INF);
  }

  void update(int i, const Type &x) {
    i += size - 1;

    maxvalue[i] = x;

    while (i > 0) {
      i = (i - 1) / 2;

      maxvalue[i] = max(maxvalue[2 * i + 1], maxvalue[2 * i + 2]);
    }
  }

  Type query(int s, int t) { return _query(s, t, 0, 0, size); }
};

#include <cstdio>

int main() {
  int power[16];
  power[0] = 1;

  for (int i = 1; i < 16; i++) {
    power[i] = power[i - 1] * 3;
  }

  int N;
  long long D;

  scanf("%d", &N);
  scanf("%lld", &D);

  int mid = N / 2;

  int power1 = power[mid];
  int power2 = power[N - mid];

  vector<long long> X(N);
  vector<long long> Y(N);

  for (int i = 0; i < N; i++) {
    scanf("%lld", &X[i]);
    scanf("%lld", &Y[i]);
  }

  vector<long long> D1X, D1Y;

  vector<pair<long long, long long>> D2;

  long long X3, Y3;

  for (int i = 0; i < power1; i++) {
    X3 = 0LL;
    Y3 = 0LL;

    for (int j = 0; j < mid; j++) {
      switch ((i / power[j]) % 3) {
      case 0:
        X3 -= X[j];
        Y3 -= Y[j];
        break; // Anna
      case 1:
        X3 += X[j];
        Y3 += Y[j];
        break; // Bruno
      }
    }

    D1X.push_back(X3);
    D1Y.push_back(Y3);
  }

  for (int i = 0; i < power2; i++) {
    X3 = 0LL;
    Y3 = 0LL;

    for (int j = mid; j < N; j++) {
      switch ((i / power[j - mid]) % 3) {
      case 0:
        X3 -= X[j];
        Y3 -= Y[j];
        break; // Anna
      case 1:
        X3 += X[j];
        Y3 += Y[j];
        break; // Bruno
      }
    }

    D2.push_back(make_pair(X3, Y3));
  }

  sort(D2.begin(), D2.end(),
       [](pair<long long, long long> x, pair<long long, long long> y) {
         return x.first < y.first;
       });

  int D1_size = D1X.size();
  int D2_size = D2.size();

  vector<long long> X1;

  RMQ<long long> rmq(N != 30 ? D2_size : 0);

  if (N != 30) {
    for (int i = 0; i < D2_size; i++) {
      X1.push_back(D2[i].first);

      rmq.update(i, D2[i].second);
    }
  } else {
    for (int i = 0; i < D2_size; i++) {
      X1.push_back(D2[i].first);
    }
  }

  long long Ans = INF;

  int ptr1, ptr2;

  if (N != 30) {
    for (int i = 0; i < D1_size; i++) {
      long long _D1X = -D1X[i];

      ptr1 = distance(X1.begin(), lower_bound(X1.begin(), X1.end(), _D1X - D));
      ptr2 = distance(X1.begin(), upper_bound(X1.begin(), X1.end(), _D1X + D));

      if (ptr1 != ptr2) {
        Ans = max(D1Y[i] + rmq.query(ptr1, ptr2), Ans);
      }
    }
  } else {
    for (int i = 0; i < D1_size; i++) {
      long long _D1X = -D1X[i];

      ptr1 = distance(X1.begin(), lower_bound(X1.begin(), X1.end(), _D1X - D));
      ptr2 = distance(X1.begin(), upper_bound(X1.begin(), X1.end(), _D1X + D));

      for (int j = ptr1; j < ptr2; j++) {
        Ans = max(D1Y[i] + D2[j].second, Ans);
      }
    }
  }

  printf("%lld\\n", Ans);

  return 0;
}