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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 1e18
#define INF 1e9

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) x.begin(), x.end()

#define fst first
#define snd second

using namespace std;

using ll = long long;
using PII = pair<int, int>;
using PLL = pair<ll, ll>;
using PLLL = pair<ll, PLL>;

ll MOD = 1e9 + 7;
ll N, Nh, D, total = 0;
PLL tre[31];
vector<PLL> s;
vector<PLL> s1;
ll sz = 1;
vector<PLL> dat;

void set_val(int i, PLL x) {
  i += sz - 1;
  dat[i] = x;
  while (i > 0) {
    i = (i - 1) / 2;
    if (dat[i * 2 + 1].second < dat[i * 2 + 2].second) {
      dat[i] = dat[i * 2 + 2];
    } else {
      dat[i] = dat[i * 2 + 1];
    }
  }
}

ll query(int a, int b, int l, int r, int k) {
  if (b <= l || r <= a)
    return -INF_LL;
  if (a <= l && r <= b) {
    return dat[k].second;
  } else {
    ll res = max(query(a, b, l, (l + r) / 2, k * 2 + 1),
                 query(a, b, (l + r) / 2, r, k * 2 + 2));
    return res;
  }
}

bool comp(PLL lhs, PLL rhs) { return lhs.first < rhs.first; }

void dfs1(int n, int lim, ll sum_ap, ll sum_ar, ll sum_bp, ll sum_br) {
  if (n == lim) {
    s.push_back({sum_bp - sum_ap, {sum_br - sum_ar}});
    return;
  }
  dfs1(n + 1, lim, sum_ap, sum_ar, sum_bp, sum_br);
  dfs1(n + 1, lim, sum_ap + tre[n].first, sum_ar + tre[n].second, sum_bp,
       sum_br);
  dfs1(n + 1, lim, sum_ap, sum_ar, sum_bp + tre[n].first,
       sum_br + tre[n].second);
}

int main(void) {
  cin >> N >> D;
  Nh = N / 2;
  REP(i, N) { cin >> tre[i].first >> tre[i].second; }
  dfs1(0, Nh, 0, 0, 0, 0);
  sort(all(s));
  REP(i, s.size()) {
    int in = i;
    ll max_v = -INF_LL;
    while (s[in].first == s[i].first && in < s.size()) {
      max_v = max(max_v, s[in].second);
      in++;
    }
    s1.push_back({s[i].first, max_v});
    i = in - 1;
  }
  s1.push_back({INF_LL, 0});
  s = vector<PLL>();
  dfs1(Nh, N, 0, 0, 0, 0);
  sort(all(s));
  reverse(all(s));
  while (sz < s1.size())
    sz *= 2;
  REP(i, sz * 2 - 1) { dat.push_back({INF_LL, 0}); }

  REP(i, s1.size()) { set_val(i, s1[i]); }

  ll res = -INF_LL;
  ll l = 0, r = 0;
  REP(i, s.size()) {
    ll rare = s[i].second;
    ll price = s[i].first;
    l = lower_bound(all(s1), make_pair(-D - price, (ll)-INF_LL)) - s1.begin();
    r = upper_bound(all(s1), make_pair(D - price, (ll)INF_LL)) - s1.begin();

    res = max(res, query(l, r, 0, sz, 0) + rare);
  }
  cout << res << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 1e18
#define INF 1e9

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) x.begin(), x.end()

#define fst first
#define snd second

using namespace std;

using ll = long long;
using PII = pair<int, int>;
using PLL = pair<ll, ll>;
using PLLL = pair<ll, PLL>;

ll MOD = 1e9 + 7;
ll N, Nh, D, total = 0;
PLL tre[31];
vector<PLL> s;
vector<PLL> s1;
ll sz = 1;
vector<PLL> dat;

void set_val(int i, PLL x) {
  i += sz - 1;
  dat[i] = x;
  while (i > 0) {
    i = (i - 1) / 2;
    if (dat[i * 2 + 1].second < dat[i * 2 + 2].second) {
      dat[i] = dat[i * 2 + 2];
    } else {
      dat[i] = dat[i * 2 + 1];
    }
  }
}

ll query(int a, int b, int l, int r, int k) {
  if (b <= l || r <= a)
    return -INF_LL;
  if (a <= l && r <= b) {
    return dat[k].second;
  } else {
    ll res = max(query(a, b, l, (l + r) / 2, k * 2 + 1),
                 query(a, b, (l + r) / 2, r, k * 2 + 2));
    return res;
  }
}

bool comp(PLL lhs, PLL rhs) { return lhs.first < rhs.first; }

void dfs1(int n, int lim, ll sum_ap, ll sum_ar, ll sum_bp, ll sum_br) {
  if (n == lim) {
    s.push_back({sum_bp - sum_ap, {sum_br - sum_ar}});
    return;
  }
  dfs1(n + 1, lim, sum_ap, sum_ar, sum_bp, sum_br);
  dfs1(n + 1, lim, sum_ap + tre[n].first, sum_ar + tre[n].second, sum_bp,
       sum_br);
  dfs1(n + 1, lim, sum_ap, sum_ar, sum_bp + tre[n].first,
       sum_br + tre[n].second);
}

int main(void) {
  cin >> N >> D;
  Nh = N / 2;
  REP(i, N) { cin >> tre[i].first >> tre[i].second; }
  dfs1(0, Nh, 0, 0, 0, 0);
  sort(all(s));
  REP(i, s.size()) {
    int in = i;
    ll max_v = -INF_LL;
    while (s[in].first == s[i].first && in < s.size()) {
      max_v = max(max_v, s[in].second);
      in++;
    }
    s1.push_back({s[i].first, max_v});
    i = in - 1;
  }
  s1.push_back({INF_LL, 0});
  s = vector<PLL>();
  dfs1(Nh, N, 0, 0, 0, 0);
  sort(all(s));
  reverse(all(s));
  while (sz < s1.size())
    sz *= 2;
  REP(i, sz * 2 - 1) { dat.push_back({INF_LL, 0}); }

  REP(i, s1.size()) { set_val(i, s1[i]); }

  ll res = -INF_LL;
  ll l = 0, r = 0;
  REP(i, s.size()) {
    ll rare = s[i].second;
    ll price = s[i].first;
    while (s1[l].first < -D - price)
      l++;
    r = l;
    while (s1[r].first <= D - price)
      r++;
    res = max(res, query(l, r, 0, sz, 0) + rare);
  }
  cout << res << endl;
}