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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long

#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;

template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> T get() {
  T a;
  cin >> a;
  return a;
}
template <typename T> T rev(T a) {
  reverse(all(a));
  return a;
}
template <typename T> vector<T> &sort(vector<T> &a) {
  sort(all(a));
  return a;
}

const int inf = 3e18;
const double eps = 1e-9;

struct Data {
  int fst, scd;
  Data(int fst, int scd) : fst(fst), scd(scd) {}
  bool operator<(const Data &d) const {
    if (fst == d.fst)
      return scd < d.scd;
    return fst < d.fst;
  }
  bool operator>(const Data &d) const {
    if (fst == d.fst)
      return scd > d.scd;
    return fst > d.fst;
  }
};

struct RMQ {
  vi dat;
  int n;

  RMQ(int n_) {
    n = 1;

    while (n < n_)
      n *= 2;
    dat.resize(2 * n, -inf);
  }

  inline void update(int i, int v) {
    i += n - 1;

    dat[i] = v;

    while (i > 0) {
      i = (i - 1) / 2;
      dat[i] = max(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }

  inline int query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return -inf;
    if (a <= l && r <= b)
      return dat[k];

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

    return max(vl, vr);
  }
};

vector<Data> treasures;
vector<Data> half1, half2;
int A[15000000];
int B[15000000];

signed
main() { // #define int long long
         // ?????????????????§scanf???????????¨???????????????????????\\?????????????????????
  omajinai;
  int N, D;
  cin >> N >> D;

  rep(i, N) {
    int X, Y;
    cin >> X >> Y;
    treasures.PB(Data(X, Y));
  }

  for (int i = 0, n = N / 2 + N % 2, len = pow(3, n); i < len; ++i) {
    int diff1 = 0, diff2 = 0;

    for (int j = 0, I = i; j < n; ++j) {
      switch (I % 3) {
      case 0:
        break;
      case 1:
        diff1 += treasures[N / 2 + j].fst;
        diff2 -= treasures[N / 2 + j].scd;
        break;
      case 2:
        diff1 -= treasures[N / 2 + j].fst;
        diff2 += treasures[N / 2 + j].scd;
        break;
      }

      I /= 3;
    }

    half2.PB(Data(diff1, diff2));
  }

  RMQ rmq(half2.size());

  sort(all(half2));

  rep(i, half2.size()) {
    A[i] = half2[i].fst;
    B[i] = half2[i].scd;

    rmq.update(i, B[i]);
  }

  int ans = -inf;

  for (int i = 0, n = N / 2, len = pow(3, n); i < len; ++i) {
    int diff1 = 0, diff2 = 0;

    for (int j = 0, I = i; j < n; ++j) {
      switch (I % 3) {
      case 0:
        break;
      case 1:
        diff1 += treasures[j].fst;
        diff2 -= treasures[j].scd;
        break;
      case 2:
        diff1 -= treasures[j].fst;
        diff2 += treasures[j].scd;
        break;
      }

      I /= 3;
    }

    half1.PB(Data(diff1, diff2));
  }

  sort(all(half1), greater<Data>());

  int lidx = 0, ridx = 0;

  rep(i, half1.size()) {
    Data &da = half1[i];

    int lv = min(-D - da.fst, D - da.fst);
    int rv = max(-D - da.fst, D - da.fst);

    while (A[lidx] < lv && lidx + 1 < half2.size())
      lidx++;
    while ((lidx > ridx) || (A[ridx] <= rv && ridx + 1 < half2.size()))
      ridx++;
    ridx--;

    if (lidx > ridx)
      continue;

    ans = max(ans, da.scd + rmq.query(lidx, ridx + 1));
  }

  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long

#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;

template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> T get() {
  T a;
  cin >> a;
  return a;
}
template <typename T> T rev(T a) {
  reverse(all(a));
  return a;
}
template <typename T> vector<T> &sort(vector<T> &a) {
  sort(all(a));
  return a;
}

const int inf = 3e18;
const double eps = 1e-9;

struct Data {
  int fst, scd;
  Data(int fst, int scd) : fst(fst), scd(scd) {}
  bool operator<(const Data &d) const { return fst < d.fst; }
};

struct RMQ {
  vi dat;
  int n;

  RMQ(int n_) {
    n = 1;

    while (n < n_)
      n *= 2;
    dat.resize(2 * n, -inf);
  }

  inline void update(int i, int v) {
    i += n - 1;

    dat[i] = v;

    while (i > 0) {
      i = (i - 1) / 2;
      dat[i] = max(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }

  inline int query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return -inf;
    if (a <= l && r <= b)
      return dat[k];

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

    return max(vl, vr);
  }
};

vector<Data> treasures;
vector<Data> half1, half2;
int A[15000000];
int B[15000000];

signed
main() { // #define int long long
         // ?????????????????§scanf???????????¨???????????????????????\\?????????????????????
  omajinai;
  int N, D;
  cin >> N >> D;

  rep(i, N) {
    int X, Y;
    cin >> X >> Y;
    treasures.PB(Data(X, Y));
  }

  for (int i = 0, n = N / 2 + N % 2, len = pow(3, n); i < len; ++i) {
    int diff1 = 0, diff2 = 0;

    for (int j = 0, I = i; j < n; ++j) {
      switch (I % 3) {
      case 0:
        break;
      case 1:
        diff1 += treasures[N / 2 + j].fst;
        diff2 -= treasures[N / 2 + j].scd;
        break;
      case 2:
        diff1 -= treasures[N / 2 + j].fst;
        diff2 += treasures[N / 2 + j].scd;
        break;
      }

      I /= 3;
    }

    half2.PB(Data(diff1, diff2));
  }

  RMQ rmq(half2.size());

  sort(all(half2));

  rep(i, half2.size()) {
    A[i] = half2[i].fst;
    B[i] = half2[i].scd;

    rmq.update(i, B[i]);
  }

  int ans = -inf;

  for (int i = 0, n = N / 2, len = pow(3, n); i < len; ++i) {
    int diff1 = 0, diff2 = 0;

    for (int j = 0, I = i; j < n; ++j) {
      switch (I % 3) {
      case 0:
        break;
      case 1:
        diff1 += treasures[j].fst;
        diff2 -= treasures[j].scd;
        break;
      case 2:
        diff1 -= treasures[j].fst;
        diff2 += treasures[j].scd;
        break;
      }

      I /= 3;
    }

    half1.PB(Data(diff1, diff2));
    int lv = min(-D - diff1, D - diff1);
    int rv = max(-D - diff1, D - diff1);

    int lidx = lower_bound(A, A + half2.size(), lv) - A;
    int ridx = upper_bound(A, A + half2.size(), rv) - A - 1;

    ans = max(ans, diff2 + rmq.query(lidx, ridx + 1));
  }

  cout << ans << endl;
}