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

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int inf = 1e18;
typedef pair<int, int> P;
#define MAX 35000000

int price[32], value[32], segn = 1;
int segmax[MAX];
vector<P> a[2];

void dfs(int k, int t, int u, int pri, int val) {
  if (k == t) {
    a[u].push_back(P(pri, val));
    return;
  }
  dfs(k + 1, t, u, pri + price[k], val + value[k]);
  dfs(k + 1, t, u, pri - price[k], val - value[k]);
  dfs(k + 1, t, u, pri, val);
}

void init(int n) {
  while (segn < n)
    segn *= 2;
  for (int i = 0; i < segn * 2; i++)
    segmax[i] = -inf;
}

void add(int k, int val) {
  k += segn - 1;
  segmax[k] = val;
  while (k) {
    k = (k - 1) / 2;
    segmax[k] = max(segmax[k * 2 + 1], segmax[k * 2 + 2]);
  }
}

int getmax(int a, int b, int k, int l, int r) {
  if (b <= l || r <= a)
    return -inf;
  if (a <= l && r <= b)
    return segmax[k];
  int t1 = getmax(a, b, k * 2 + 1, l, (l + r) / 2);
  int t2 = getmax(a, b, k * 2 + 2, (l + r) / 2, r);
  return max(t1, t2);
}

signed main() {
  int n, d;
  scanf("%lld%lld", &n, &d);
  for (int i = 0; i < n; i++)
    scanf("%lld%lld", &price[i], &value[i]);

  int m = n / 2;
  n = n - m;
  dfs(0, n, 0, 0, 0);
  dfs(n, n + m, 1, 0, 0);

  sort(a[0].begin(), a[0].end());
  sort(a[1].begin(), a[1].end(), greater<P>());

  init(a[1].size());
  for (int i = 0; i < a[1].size(); i++) {
    add(i, a[1][i].se);
  }

  int l = 0, r = 0, ans = 0;
  for (int i = 0; i < a[0].size(); i++) {
    int bn = a[1].size(), v = a[0][i].fi, v2 = a[0][i].se;
    while (r < bn && a[1][r].fi + v >= -d)
      r++;
    while (l < bn && a[1][l].fi + v > d)
      l++;
    int mx = getmax(l, r, 0, 0, segn);
    if (mx == -inf)
      continue;
    ans = max(ans, llabs(v2 + mx));
  }

  /*for(int i = 0;i < a[0].size();i++){
          printf("%d ", a[0][i].se);
  }
  printf("\\n");
  for(int i = 0;i < a[1].size();i++){
          printf("%d ", a[1][i].se);
  }
  printf("\\n");*/
  printf("%lld\\n", ans);
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int inf = 1e18;
typedef pair<int, int> P;
#define MAX 35000000

int price[32], value[32], segn = 1;
int segmin[MAX], segmax[MAX];
vector<P> a[2];

void dfs(int k, int t, int u, int pri, int val) {
  if (k == t) {
    a[u].push_back(P(pri, val));
    return;
  }
  dfs(k + 1, t, u, pri + price[k], val + value[k]);
  dfs(k + 1, t, u, pri - price[k], val - value[k]);
  dfs(k + 1, t, u, pri, val);
}

void init(int n) {
  while (segn < n)
    segn *= 2;
  for (int i = 0; i < segn * 2; i++)
    segmin[i] = inf;
  for (int i = 0; i < segn * 2; i++)
    segmax[i] = -inf;
}

void add(int k, int val) {
  k += segn - 1;
  segmin[k] = val;
  segmax[k] = val;
  while (k) {
    k = (k - 1) / 2;
    segmin[k] = min(segmin[k * 2 + 1], segmin[k * 2 + 2]);
    segmax[k] = max(segmax[k * 2 + 1], segmax[k * 2 + 2]);
  }
}

int getmin(int a, int b, int k, int l, int r) {
  if (b <= l || r <= a)
    return inf;
  if (a <= l && r <= b)
    return segmin[k];
  int t1 = getmin(a, b, k * 2 + 1, l, (l + r) / 2);
  int t2 = getmin(a, b, k * 2 + 2, (l + r) / 2, r);
  return min(t1, t2);
}

int getmax(int a, int b, int k, int l, int r) {
  if (b <= l || r <= a)
    return -inf;
  if (a <= l && r <= b)
    return segmax[k];
  int t1 = getmax(a, b, k * 2 + 1, l, (l + r) / 2);
  int t2 = getmax(a, b, k * 2 + 2, (l + r) / 2, r);
  return max(t1, t2);
}

signed main() {
  int n, d;
  scanf("%lld%lld", &n, &d);
  for (int i = 0; i < n; i++)
    scanf("%lld%lld", &price[i], &value[i]);

  int m = n / 2;
  n = n - m;
  dfs(0, n, 0, 0, 0);
  dfs(n, n + m, 1, 0, 0);

  sort(a[0].begin(), a[0].end());
  sort(a[1].begin(), a[1].end(), greater<P>());
  // printf("%lld %lld\\n", a[0].size(), a[1].size());

  init(a[1].size());
  for (int i = 0; i < a[1].size(); i++) {
    add(i, a[1][i].se);
  }
  // printf("%d\\n", getmin(1, 3, 0, 0, segn));

  int l = 0, r = 0, ans = 0;
  for (int i = 0; i < a[0].size(); i++) {
    int bn = a[1].size(), v = a[0][i].fi, v2 = a[0][i].se;
    while (r < bn && a[1][r].fi + v >= -d)
      r++;
    while (l < bn && a[1][l].fi + v > d)
      l++;
    // printf("%d %d\\n", l, r);
    int mn = getmin(l, r, 0, 0, segn);
    int mx = getmax(l, r, 0, 0, segn);
    if (mn == inf)
      continue;
    int res = max(llabs(v2 + mn), llabs(v2 + mx)); // long long注意
    ans = max(ans, res);
    // printf("%d\\n", ans);
  }

  /*for(int i = 0;i < a[0].size();i++){
          printf("%d ", a[0][i].se);
  }
  printf("\\n");
  for(int i = 0;i < a[1].size();i++){
          printf("%d ", a[1][i].se);
  }
  printf("\\n");*/
  printf("%lld\\n", ans);
}