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

#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
#define rep(i, x) for (ll i = 0; i < (ll)(x); i++)
#define rrep(i, x) for (ll i = (ll)(x)-1; 0 <= i; i--)
#define reps(i, x) for (ll i = 1; i < (ll)(x) + 1; i++)
#define rreps(i, x) for (ll i = (ll)(x); 1 <= i; i--)
#define all(x) (x).begin(), (x).end()
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> Pll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
constexpr ll INF = numeric_limits<ll>::max() / 4;
constexpr ll n_max = 2e5 + 10;
#define int ll

template <typename A, typename B> string to_string(pair<A, B> p);
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char c) { return to_string((string)&c); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <size_t N> string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++)
    res += static_cast<char>('0' + v[i]);
  return res;
}
template <typename A> string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first)
      res += ", ";
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <class T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <std::int_fast64_t Modulus> class modint {
  using i64 = int_fast64_t;

public:
  i64 a;

  constexpr modint(const i64 x = 0) noexcept {
    this->a = x % Modulus;
    if (a < 0) {
      a += Modulus;
    }
  }
  constexpr int getmod() { return Modulus; }
  constexpr modint operator-() const noexcept { return a ? Modulus - a : 0; }
  constexpr const i64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    i64 a_ = rhs.a, b = Modulus, u = 1, v = 0;
    while (b) {
      i64 t = a_ / b;
      a_ -= t * b;
      swap(a_, b);
      u -= t * v;
      swap(u, v);
    }
    a = a * u % Modulus;
    if (a < 0)
      a += Modulus;
    return *this;
  }

  // 自前実装
  constexpr bool operator==(const modint rhs) noexcept { return a == rhs.a; }
  constexpr bool operator!=(const modint rhs) noexcept { return a != rhs.a; }
  constexpr bool operator>(const modint rhs) noexcept { return a > rhs.a; }
  constexpr bool operator>=(const modint rhs) noexcept { return a >= rhs.a; }
  constexpr bool operator<(const modint rhs) noexcept { return a < rhs.a; }
  constexpr bool operator<=(const modint rhs) noexcept { return a <= rhs.a; }
  constexpr modint &operator++() noexcept { return (*this) += modint(1); }
  // constexpr modint operator++(int) {
  //     modint tmp(*this);
  //     operator++();
  //     return tmp;
  // }
  constexpr modint &operator--() noexcept { return (*this) -= modint(1); }
  // constexpr modint operator--(int) {
  //     modint tmp(*this);
  //     operator--();
  //     return tmp;
  // }
  template <typename T>
  friend constexpr modint modpow(const modint &mt, T n) noexcept {
    if (n < 0) {
      modint t = (modint(1) / mt);
      return modpow(t, -n);
    }
    modint res = 1, tmp = mt;
    while (n) {
      if (n & 1)
        res *= tmp;
      tmp *= tmp;
      n /= 2;
    }
    return res;
  }
};

const ll MOD = 998244353;
using mint = modint<MOD>;
// 標準入出力対応
std::ostream &operator<<(std::ostream &out, const modint<MOD> &m) {
  out << m.a;
  return out;
}
std::istream &operator>>(std::istream &in, modint<MOD> &m) {
  ll a;
  in >> a;
  m = mint(a);
  return in;
}

string to_string(mint m) { return to_string(m.a); }
signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ll n, s;
  cin >> n >> s;
  vector<ll> a(n);
  rep(i, n) cin >> a[i];
  vector<vector<mint>> dp(n + 1, vector<mint>(s + 10));
  dp[0][0] = 1;
  rep(i, n) {
    rep(j, s + 1) {
      dp[i + 1][j] += dp[i][j] * 2;
      if (j >= a[i])
        dp[i + 1][j] += dp[i][j - a[i]];
    }
  }

  cout << dp[n][s] << endl;
}

Error: TLE

Fixed submission:

#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
#define rep(i, x) for (ll i = 0; i < (ll)(x); i++)
#define rrep(i, x) for (ll i = (ll)(x)-1; 0 <= i; i--)
#define reps(i, x) for (ll i = 1; i < (ll)(x) + 1; i++)
#define rreps(i, x) for (ll i = (ll)(x); 1 <= i; i--)
#define all(x) (x).begin(), (x).end()
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> Pll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
constexpr ll INF = numeric_limits<ll>::max() / 4;
constexpr ll n_max = 2e5 + 10;
#define int ll

template <typename A, typename B> string to_string(pair<A, B> p);
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char c) { return to_string((string)&c); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <size_t N> string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++)
    res += static_cast<char>('0' + v[i]);
  return res;
}
template <typename A> string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first)
      res += ", ";
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <class T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <std::int_fast64_t Modulus> class modint {
  using i64 = int_fast64_t;

public:
  i64 a;

  constexpr modint(const i64 x = 0) noexcept {
    this->a = x % Modulus;
    if (a < 0) {
      a += Modulus;
    }
  }
  constexpr int getmod() { return Modulus; }
  constexpr modint operator-() const noexcept { return a ? Modulus - a : 0; }
  constexpr const i64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    i64 a_ = rhs.a, b = Modulus, u = 1, v = 0;
    while (b) {
      i64 t = a_ / b;
      a_ -= t * b;
      swap(a_, b);
      u -= t * v;
      swap(u, v);
    }
    a = a * u % Modulus;
    if (a < 0)
      a += Modulus;
    return *this;
  }

  // 自前実装
  constexpr bool operator==(const modint rhs) noexcept { return a == rhs.a; }
  constexpr bool operator!=(const modint rhs) noexcept { return a != rhs.a; }
  constexpr bool operator>(const modint rhs) noexcept { return a > rhs.a; }
  constexpr bool operator>=(const modint rhs) noexcept { return a >= rhs.a; }
  constexpr bool operator<(const modint rhs) noexcept { return a < rhs.a; }
  constexpr bool operator<=(const modint rhs) noexcept { return a <= rhs.a; }
  constexpr modint &operator++() noexcept { return (*this) += modint(1); }
  // constexpr modint operator++(int) {
  //     modint tmp(*this);
  //     operator++();
  //     return tmp;
  // }
  constexpr modint &operator--() noexcept { return (*this) -= modint(1); }
  // constexpr modint operator--(int) {
  //     modint tmp(*this);
  //     operator--();
  //     return tmp;
  // }
  template <typename T>
  friend constexpr modint modpow(const modint &mt, T n) noexcept {
    if (n < 0) {
      modint t = (modint(1) / mt);
      return modpow(t, -n);
    }
    modint res = 1, tmp = mt;
    while (n) {
      if (n & 1)
        res *= tmp;
      tmp *= tmp;
      n /= 2;
    }
    return res;
  }
};

const ll MOD = 998244353;
using mint = modint<MOD>;
// 標準入出力対応
std::ostream &operator<<(std::ostream &out, const modint<MOD> &m) {
  out << m.a;
  return out;
}
std::istream &operator>>(std::istream &in, modint<MOD> &m) {
  ll a;
  in >> a;
  m = mint(a);
  return in;
}

string to_string(mint m) { return to_string(m.a); }

signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ll n, s;
  cin >> n >> s;
  vector<ll> a(n);
  rep(i, n) cin >> a[i];
  vector<vector<mint>> dp(n + 1, vector<mint>(s + 10));
  dp[0][0] = 1;
  rep(i, n) {
    rrep(k, i + 1) {
      rep(j, s + 1) {
        if (j >= a[i])
          dp[k + 1][j] += dp[k][j - a[i]];
        // dp[k+1][j] += dp[k][j];
      }
    }
  }
  debug(dp);
  mint ans = 0;
  reps(i, n) { ans += modpow(mint(2), (n - i)) * dp[i][s]; }

  cout << ans << endl;
}