Problem p03165 (C++)

Buggy submission (status: Memory Limit Exceeded):


#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <time.h>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <vector>

using namespace std;

#define rep(i, N, M) for (ll i = N, i##_len = (M); i < i##_len; ++i)
#define rep_skip(i, N, M, ...)                                                 \
  for (ll i = N, i##_len = (M); i < i##_len; i += (skip))
#define rrep(i, N, M) for (ll i = (M)-1, i##_len = (N - 1); i > i##_len; --i)
#define pb push_back

typedef pair<double, double> pd;

typedef long long ll;
typedef pair<ll, ll> pll;

constexpr ll MOD = 1000000007;
constexpr ll INF = 1LL << 62;

template <int n> struct tll_impl {
  using type = decltype(tuple_cat(tuple<ll>(),
                                  declval<typename tll_impl<n - 1>::type>()));
};
template <> struct tll_impl<1> {
  using type = tuple<ll>;
};
template <int n> using tll = typename tll_impl<n>::type;

template <class T> constexpr ll SZ(T &v) { return static_cast<ll>(v.size()); };

template <int n, typename T> struct vec_t_impl {
  using type = vector<typename vec_t_impl<n - 1, T>::type>;
};
template <typename T> struct vec_t_impl<1, T> {
  using type = vector<T>;
};
template <int n, typename T> using vec_t = typename vec_t_impl<n, T>::type;
// check
static_assert(is_same<vec_t<3, ll>, vector<vector<vector<ll>>>>::value, "");

// decompose vector into basetype and dimension.
template <typename T> struct vec_dec {
  static constexpr int dim = 0;
  using type = T;
};
template <typename T> struct vec_dec<vector<T>> {
  static constexpr int dim = vec_dec<T>::dim + 1;
  using type = typename vec_dec<T>::type;
};
static_assert(is_same<typename vec_dec<vec_t<3, ll>>::type, ll>::value, "");
static_assert(vec_dec<vec_t<3, ll>>::dim == 3, "");

template <typename T = ll> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T = ll, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
// ex:  auto dp =  make_v<ll>(4,5) => vector<vector<ll>> dp(4,vector<ll>(5));

// check if T is vector
template <typename T> struct is_vector : std::false_type {};

template <typename T> struct is_vector<vector<T>> : std::true_type {};

template <typename T, typename V>
typename enable_if<!is_vector<T>::value>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_vector<T>::value>::type fill_v(T &t, const V &v) {
  for (auto &&x : t)
    fill_v(x, v);
}
// ex:  fill_v(dp, INF);

typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<pll> vpll;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<string> vs;
template <typename T>
using pq_greater = priority_queue<T, vector<T>, greater<T>>;

#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define perm(c)                                                                \
  sort(all(c));                                                                \
  for (bool c##perm = 1; c##perm; c##perm = next_permutation(all(c)))

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

vll seq(ll i, ll j) {
  vll res(j - i);
  rep(k, i, j) res[k] = i + k;
  return res;
}

constexpr ll POW_(ll n, ll m) {
  ll res = 1;
  rep(i, 0, m) { res *= n; }
  return res;
}

template <ll mod = 0> constexpr ll POW(ll x, ll n) {
  if (x == 2) {
    return (1LL << n) % mod;
  }
  if (n == 0)
    return 1;
  if (n == 1)
    return x % mod;
  if (n % 2 == 0)
    return POW_(POW<mod>(x, n / 2), 2LL) % mod;
  return ((POW_(POW<mod>(x, n / 2), 2LL) % mod) * (x % mod)) % mod;
}
template <> constexpr ll POW<0>(ll x, ll n) {
  if (x == 2) {
    return 1LL << n;
  }
  if (n == 0)
    return 1;
  if (n == 1)
    return x;
  if (n % 2 == 0)
    return POW_(POW(x, n / 2), 2);
  return (POW_(POW(x, n / 2), 2)) * x;
}

template <typename Inputs, typename Functor,
          typename T = typename Inputs::value_type>
void sort_by(Inputs &inputs, Functor f) {
  std::sort(std::begin(inputs), std::end(inputs),
            [&f](const T &lhs, const T &rhs) { return f(lhs) < f(rhs); });
}

template <typename Inputs, typename Functor,
          typename T = typename Inputs::value_type>
void stable_sort_by(Inputs &inputs, Functor f) {
  std::stable_sort(
      std::begin(inputs), std::end(inputs),
      [&f](const T &lhs, const T &rhs) { return f(lhs) < f(rhs); });
}

// ============================ Header  =================================

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  string s, t;
  cin >> s >> t;
  auto dp = make_v(s.size() + 1, t.size() + 1);
  auto dps = make_v<string>(s.size() + 1, t.size() + 1);
  rep(i, 0, s.size()) rep(j, 0, t.size()) {
    dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]);
    dps[i + 1][j + 1] =
        (dp[i + 1][j] > dp[i][j + 1] ? dps[i + 1][j] : dps[i][j + 1]);
    if (s[i] == t[j]) {
      if (dp[i][j] + 1 > max(dp[i + 1][j], dp[i][j + 1])) {
        dp[i + 1][j + 1] = dp[i][j] + 1;
        dps[i + 1][j + 1] = dps[i][j] + s[i];
      }
    }
    dps[i][j] = "";
  }

  cout << dps[s.size()][t.size()] << endl;
  return 0;
}


Fixed submission:


#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <time.h>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <vector>

using namespace std;

#define rep(i, N, M) for (ll i = N, i##_len = (M); i < i##_len; ++i)
#define rep_skip(i, N, M, ...)                                                 \
  for (ll i = N, i##_len = (M); i < i##_len; i += (skip))
#define rrep(i, N, M) for (ll i = (M)-1, i##_len = (N - 1); i > i##_len; --i)
#define pb push_back

typedef pair<double, double> pd;

typedef long long ll;
typedef pair<ll, ll> pll;

constexpr ll MOD = 1000000007;
constexpr ll INF = 1LL << 62;

template <int n> struct tll_impl {
  using type = decltype(tuple_cat(tuple<ll>(),
                                  declval<typename tll_impl<n - 1>::type>()));
};
template <> struct tll_impl<1> {
  using type = tuple<ll>;
};
template <int n> using tll = typename tll_impl<n>::type;

template <class T> constexpr ll SZ(T &v) { return static_cast<ll>(v.size()); };

template <int n, typename T> struct vec_t_impl {
  using type = vector<typename vec_t_impl<n - 1, T>::type>;
};
template <typename T> struct vec_t_impl<1, T> {
  using type = vector<T>;
};
template <int n, typename T> using vec_t = typename vec_t_impl<n, T>::type;
// check
static_assert(is_same<vec_t<3, ll>, vector<vector<vector<ll>>>>::value, "");

// decompose vector into basetype and dimension.
template <typename T> struct vec_dec {
  static constexpr int dim = 0;
  using type = T;
};
template <typename T> struct vec_dec<vector<T>> {
  static constexpr int dim = vec_dec<T>::dim + 1;
  using type = typename vec_dec<T>::type;
};
static_assert(is_same<typename vec_dec<vec_t<3, ll>>::type, ll>::value, "");
static_assert(vec_dec<vec_t<3, ll>>::dim == 3, "");

template <typename T = ll> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T = ll, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
// ex:  auto dp =  make_v<ll>(4,5) => vector<vector<ll>> dp(4,vector<ll>(5));

// check if T is vector
template <typename T> struct is_vector : std::false_type {};

template <typename T> struct is_vector<vector<T>> : std::true_type {};

template <typename T, typename V>
typename enable_if<!is_vector<T>::value>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_vector<T>::value>::type fill_v(T &t, const V &v) {
  for (auto &&x : t)
    fill_v(x, v);
}
// ex:  fill_v(dp, INF);

typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<pll> vpll;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<string> vs;
template <typename T>
using pq_greater = priority_queue<T, vector<T>, greater<T>>;

#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define perm(c)                                                                \
  sort(all(c));                                                                \
  for (bool c##perm = 1; c##perm; c##perm = next_permutation(all(c)))

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

vll seq(ll i, ll j) {
  vll res(j - i);
  rep(k, i, j) res[k] = i + k;
  return res;
}

constexpr ll POW_(ll n, ll m) {
  ll res = 1;
  rep(i, 0, m) { res *= n; }
  return res;
}

template <ll mod = 0> constexpr ll POW(ll x, ll n) {
  if (x == 2) {
    return (1LL << n) % mod;
  }
  if (n == 0)
    return 1;
  if (n == 1)
    return x % mod;
  if (n % 2 == 0)
    return POW_(POW<mod>(x, n / 2), 2LL) % mod;
  return ((POW_(POW<mod>(x, n / 2), 2LL) % mod) * (x % mod)) % mod;
}
template <> constexpr ll POW<0>(ll x, ll n) {
  if (x == 2) {
    return 1LL << n;
  }
  if (n == 0)
    return 1;
  if (n == 1)
    return x;
  if (n % 2 == 0)
    return POW_(POW(x, n / 2), 2);
  return (POW_(POW(x, n / 2), 2)) * x;
}

template <typename Inputs, typename Functor,
          typename T = typename Inputs::value_type>
void sort_by(Inputs &inputs, Functor f) {
  std::sort(std::begin(inputs), std::end(inputs),
            [&f](const T &lhs, const T &rhs) { return f(lhs) < f(rhs); });
}

template <typename Inputs, typename Functor,
          typename T = typename Inputs::value_type>
void stable_sort_by(Inputs &inputs, Functor f) {
  std::stable_sort(
      std::begin(inputs), std::end(inputs),
      [&f](const T &lhs, const T &rhs) { return f(lhs) < f(rhs); });
}

// ============================ Header  =================================

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  string s, t;
  cin >> s >> t;
  auto dp = make_v(s.size() + 1, t.size() + 1);
  auto dps = make_v<string>(s.size() + 1, t.size() + 1);
  rep(i, 0, s.size()) rep(j, 0, t.size()) {
    dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]);
    dps[i + 1][j + 1] =
        (dp[i + 1][j] > dp[i][j + 1] ? dps[i + 1][j] : dps[i][j + 1]);
    if (s[i] == t[j]) {
      if (dp[i][j] + 1 > max(dp[i + 1][j], dp[i][j + 1])) {
        dp[i + 1][j + 1] = dp[i][j] + 1;
        dps[i + 1][j + 1] = dps[i][j] + s[i];
      }
    }
    string().swap(dps[i][j]);
  }

  cout << dps[s.size()][t.size()] << endl;
  return 0;
}