Problem p03780 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < int(n); i++)
#define rep1(i, n) for (int i = 1; i <= int(n); i++)
#define repR(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define rep1R(i, n) for (int i = int(n); i >= 1; i--)
#define loop(i, a, B) for (int i = a; i B; i++)
#define loopR(i, a, B) for (int i = a; i B; i--)
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define fst first
#define snd second
#define cauto const auto
#ifdef LOCAL
#define dump(...)                                                              \
  cerr << "[" << __LINE__ << ":" << __FUNCTION__ << "] ",                      \
      my_dmp(#__VA_ARGS__, __VA_ARGS__)
void my_dmp(const char *) { cerr << endl; }
template <class T, class... U>
void my_dmp(const char *s, T const &x, U const &...y) {
  const char *o = "({[", *e = "]})";
  for (int i = 0; *s != '\0'; cerr << *s++) {
    if (count(o, o + 3, *s))
      i++;
    if (count(e, e + 3, *s))
      i--;
    if (!i && *s == ',')
      break;
  }
  cerr << " = " << x;
  if (*s == ',')
    cerr << ", ", s++;
  my_dmp(s, y...);
}
#else
#define dump(...)
#endif
using ll = long long;
#define int ll
template <class T> using pque_max = priority_queue<T>;
template <class T> using pque_min = priority_queue<T, vector<T>, greater<T>>;
#define CONAINER_OUTPUT                                                        \
  os << "{";                                                                   \
  for (auto const &x : v)                                                      \
    os << " " << x;                                                            \
  return os << " }";
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, deque<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, set<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, multiset<T> const &v) {
  CONAINER_OUTPUT
}
template <class T, class U>
ostream &operator<<(ostream &os, map<T, U> const &v) {
  CONAINER_OUTPUT
}
#undef CONAINER_OUTPUT
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v)
    is >> x;
  return is;
}
template <class T, class S>
ostream &operator<<(ostream &os, pair<T, S> const &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T, class S> istream &operator>>(istream &is, pair<T, S> &p) {
  return is >> p.first >> p.second;
}
struct my_Init {
  my_Init() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} my_init;

template <class T> void quit(T const &x) {
  cout << x << endl;
  exit(0);
}
template <class T> bool chmin(T &x, T const &y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &x, T const &y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}
template <class It> auto sumof(It b, It e) {
  return accumulate(b, e, typename iterator_traits<It>::value_type{});
}
////////////////////////////////
int n, k;
vector<int> a;

const int NN = 5005;
bool dp1[NN][NN], dp2[NN][NN];
vector<int> // v1[NN],
    v2[NN];

int32_t main() {
  cin >> n >> k;
  a.resize(n);
  cin >> a;

  dp1[0][0] = 1;
  rep(i, n) {
    rep(j, NN) dp1[i + 1][j] = dp1[i][j];
    rep(j, NN) if (dp1[i][j] && j + a[i] < NN) dp1[i + 1][j + a[i]] = 1;
  }
  dp2[n][0] = 1;
  repR(i, n) {
    rep(j, NN) dp2[i][j] = dp2[i + 1][j];
    rep(j, NN) if (dp2[i + 1][j] && j + a[i] < NN) dp2[i][j + a[i]] = 1;
  }
  //    rep (i,n+1) rep (j,NN) if (dp1[i][j]) v1[i].push_back(j);
  rep(i, n + 1) rep(j, NN) if (dp2[i][j]) v2[i].push_back(j);

  // //
  // rep (i,n+1) dump(i,v1[i]);
  // puts("");
  // rep (i,n+1) dump(i,v2[i]);
  // puts("");
  // //

  vector<int> need(n);
  rep(i, n) {
    rep(j, NN) if (dp1[i][j]) {
      auto it1 = lower_bound(all(v2[i + 1]), k - a[i] - j);
      auto it2 = lower_bound(all(v2[i + 1]), k - j);
      if (it1 != it2)
        need[i] = 1;
    }
  }
  cout << n - sumof(all(need)) << endl;
  // //
  // dump(need);
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < int(n); i++)
#define rep1(i, n) for (int i = 1; i <= int(n); i++)
#define repR(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define rep1R(i, n) for (int i = int(n); i >= 1; i--)
#define loop(i, a, B) for (int i = a; i B; i++)
#define loopR(i, a, B) for (int i = a; i B; i--)
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define fst first
#define snd second
#define cauto const auto
#ifdef LOCAL
#define dump(...)                                                              \
  cerr << "[" << __LINE__ << ":" << __FUNCTION__ << "] ",                      \
      my_dmp(#__VA_ARGS__, __VA_ARGS__)
void my_dmp(const char *) { cerr << endl; }
template <class T, class... U>
void my_dmp(const char *s, T const &x, U const &...y) {
  const char *o = "({[", *e = "]})";
  for (int i = 0; *s != '\0'; cerr << *s++) {
    if (count(o, o + 3, *s))
      i++;
    if (count(e, e + 3, *s))
      i--;
    if (!i && *s == ',')
      break;
  }
  cerr << " = " << x;
  if (*s == ',')
    cerr << ", ", s++;
  my_dmp(s, y...);
}
#else
#define dump(...)
#endif
using ll = long long;
#define int ll
template <class T> using pque_max = priority_queue<T>;
template <class T> using pque_min = priority_queue<T, vector<T>, greater<T>>;
#define CONAINER_OUTPUT                                                        \
  os << "{";                                                                   \
  for (auto const &x : v)                                                      \
    os << " " << x;                                                            \
  return os << " }";
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, deque<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, set<T> const &v) {
  CONAINER_OUTPUT
}
template <class T> ostream &operator<<(ostream &os, multiset<T> const &v) {
  CONAINER_OUTPUT
}
template <class T, class U>
ostream &operator<<(ostream &os, map<T, U> const &v) {
  CONAINER_OUTPUT
}
#undef CONAINER_OUTPUT
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v)
    is >> x;
  return is;
}
template <class T, class S>
ostream &operator<<(ostream &os, pair<T, S> const &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <class T, class S> istream &operator>>(istream &is, pair<T, S> &p) {
  return is >> p.first >> p.second;
}
struct my_Init {
  my_Init() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} my_init;

template <class T> void quit(T const &x) {
  cout << x << endl;
  exit(0);
}
template <class T> bool chmin(T &x, T const &y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}
template <class T> bool chmax(T &x, T const &y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}
template <class It> auto sumof(It b, It e) {
  return accumulate(b, e, typename iterator_traits<It>::value_type{});
}
////////////////////////////////
int n, k;
vector<int> a;

const int NN = 5005;
bool dp1[NN][NN], dp2[NN][NN];
vector<int> // v1[NN],
    v2[NN];

int32_t main() {
  cin >> n >> k;
  a.resize(n);
  cin >> a;

  dp1[0][0] = 1;
  rep(i, n) {
    rep(j, NN) dp1[i + 1][j] = dp1[i][j];
    rep(j, NN) if (dp1[i][j] && j + a[i] < NN) dp1[i + 1][j + a[i]] = 1;
  }
  dp2[n][0] = 1;
  repR(i, n) {
    rep(j, NN) dp2[i][j] = dp2[i + 1][j];
    rep(j, NN) if (dp2[i + 1][j] && j + a[i] < NN) dp2[i][j + a[i]] = 1;
  }
  //    rep (i,n+1) rep (j,NN) if (dp1[i][j]) v1[i].push_back(j);
  rep(i, n + 1) {
    v2[i].reserve(NN);
    rep(j, NN) if (dp2[i][j]) v2[i].push_back(j);
  }

  // //
  // rep (i,n+1) dump(i,v1[i]);
  // puts("");
  // rep (i,n+1) dump(i,v2[i]);
  // puts("");
  // //

  vector<int> need(n);
  rep(i, n) {
    rep(j, NN) if (dp1[i][j]) {
      auto it1 = lower_bound(all(v2[i + 1]), k - a[i] - j);
      auto it2 = lower_bound(all(v2[i + 1]), k - j);
      if (it1 != it2)
        need[i] = 1;
    }
  }
  cout << n - sumof(all(need)) << endl;
  // //
  // dump(need);
}