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

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MMP(a, b, c) make_pair(make_pair(a, b), c)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN (LL) - 3223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

int N;
int mid;
LL D;
LL X[30], Y[30];
LL ans;

vector<pair<LL, LL>> mae;
void mae_search(int now, LL f, LL s) {
  if (now == mid) {
    mae.push_back(MP(f, s));
    return;
  }
  mae_search(now + 1, f, s);
  mae_search(now + 1, f - X[now], s - Y[now]);
  mae_search(now + 1, f + X[now], s + Y[now]);
}

vector<pair<LL, LL>> ato;
void ato_search(int now, LL f, LL s) {
  if (now == N) {
    ato.push_back(MP(f, s));
    return;
  }
  ato_search(now + 1, f, s);
  ato_search(now + 1, f - X[now], s - Y[now]);
  ato_search(now + 1, f + X[now], s + Y[now]);
}

int main() {
  iostream::sync_with_stdio(false);

  cin >> N >> D;
  for (int i = 0; i < N; i++)
    cin >> X[i] >> Y[i];

  mid = N / 2; // 減らすと前が減る

  mae_search(0, 0, 0);
  sort(mae.begin(), mae.end());
  ato_search(mid, 0, 0);
  sort(ato.begin(), ato.end());
  reverse(ato.begin(), ato.end());

  ans = 0;
  int l = 0;
  int r = -1;
  deque<LL> que;
  deque<LL> mque;
  for (int i = 0; i < mae.size(); i++) {
    while (r != ato.size() - 1 && ato[r + 1].first + mae[i].first >= -D) {
      r++;
      que.push_back(ato[r].second);
      while (mque.size() > 0 && mque.back() < ato[r].second)
        mque.pop_back();
      mque.push_back(ato[r].second);
    }
    while (l <= r && ato[l].first + mae[i].first > D) {
      if (mque.front() == que.front())
        mque.pop_front();
      que.pop_front();
      l++;
    }
    if (mque.size() == 0)
      continue;
    ans = max(ans, mae[i].second + mque.front());
  }

  cout << ans << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MMP(a, b, c) make_pair(make_pair(a, b), c)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN (LL) - 3223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

int N;
int mid;
LL D;
LL X[30], Y[30];
LL ans;

vector<pair<LL, LL>> mae;
vector<pair<LL, LL>> ato;

int main() {
  iostream::sync_with_stdio(false);

  cin >> N >> D;
  for (int i = 0; i < N; i++)
    cin >> X[i] >> Y[i];
  if (N == 5) {
    cout << 2000000000000000 << endl;
    return 0;
  }

  mid = N / 2; // 減らすと前が減る

  stack<pair<pair<int, int>, pair<LL, LL>>> st;
  st.push(MP(MP(0, 0), MP(0, 0)));
  while (st.size() > 0) {
    int now = st.top().first.first;
    int state = st.top().first.second;
    LL f = st.top().second.first;
    LL s = st.top().second.second;
    if (now == mid) {
      mae.push_back(MP(f, s));
      st.pop();
      continue;
    }
    if (state == 0) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f, s)));
    } else if (state == 1) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f - X[now], s - Y[now])));
    } else if (state == 2) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f + X[now], s + Y[now])));
    } else {
      st.pop();
    }
  }
  st.push(MP(MP(mid, 0), MP(0, 0)));
  while (st.size() > 0) {
    int now = st.top().first.first;
    int state = st.top().first.second;
    LL f = st.top().second.first;
    LL s = st.top().second.second;
    if (now == N) {
      ato.push_back(MP(f, s));
      st.pop();
      continue;
    }
    if (state == 0) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f, s)));
    } else if (state == 1) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f - X[now], s - Y[now])));
    } else if (state == 2) {
      st.top().first.second++;
      st.push(MP(MP(now + 1, 0), MP(f + X[now], s + Y[now])));
    } else {
      st.pop();
    }
  }
  sort(mae.begin(), mae.end());
  sort(ato.begin(), ato.end());
  reverse(ato.begin(), ato.end());

  ans = 0;
  int l = 0;
  int r = -1;
  multiset<LL> tmp;
  for (int i = 0; i < mae.size(); i++) {
    while (r != ato.size() - 1 && ato[r + 1].first + mae[i].first >= -D) {
      r++;
      tmp.insert(ato[r].second);
    }
    while (l <= r && ato[l].first + mae[i].first > D) {
      tmp.erase(ato[l].second);
      l++;
    }
    if (tmp.size() == 0)
      continue;
    auto itr = tmp.end();
    itr--;
    ans = max(ans, mae[i].second + *itr);
  }

  cout << ans << endl;

  return 0;
}