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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
typedef long long ll;
using namespace std;
const ll MOD = 998244353;

template <ll mod> class ModInt {
  ll a;

public:
  constexpr ModInt(const ll a = 0) noexcept : a((a % mod + mod) % mod) {}
  constexpr ll &value() 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 >= mod)
      a -= mod;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &rhs) noexcept {
    a += mod - rhs.a;
    if (a >= mod)
      a -= mod;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &rhs) noexcept {
    a = a * rhs.a % mod;
    return *this;
  }
  constexpr ModInt pow(ll t) const noexcept {
    if (t == 0)
      return 1;
    auto ret = pow(t >> 1);
    ret *= ret;
    if (t & 1)
      ret *= *this;
    return ret;
  }
  constexpr ModInt inv() const noexcept { return pow(mod - 2); }
  constexpr ModInt operator/=(const ModInt &rhs) {
    return (*this) *= rhs.inv();
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return this->a == rhs.a;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return this->a != rhs.a;
  }
  friend constexpr ostream &operator<<(ostream &os,
                                       const ModInt &rhs) noexcept {
    return os << rhs.a;
  }
  friend constexpr istream &operator>>(istream &is, ModInt &rhs) {
    is >> rhs.a;
    return is;
  }
};
using mint = ModInt<MOD>;

int main() {
  int n, s;
  cin >> n >> s;
  vector<int> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  vector<vector<mint>> dp(n + 1, vector<mint>(s + 1));
  dp[0][0] = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j <= s; j++) {
      dp[i + 1][j] += dp[i][j] * 2;
      if (j + a[i] <= s)
        dp[i + 1][j + a[i]] += dp[i][j];
    }
  }

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

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
typedef long long ll;
using namespace std;
const ll MOD = 998244353;

template <ll mod> class ModInt {
  ll a;

public:
  constexpr ModInt(const ll a = 0) noexcept : a((a % mod + mod) % mod) {}
  constexpr ll &value() 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 >= mod)
      a -= mod;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &rhs) noexcept {
    a += mod - rhs.a;
    if (a >= mod)
      a -= mod;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &rhs) noexcept {
    a = a * rhs.a % mod;
    return *this;
  }
  constexpr ModInt pow(ll t) const noexcept {
    if (t == 0)
      return 1;
    auto ret = pow(t >> 1);
    ret *= ret;
    if (t & 1)
      ret *= *this;
    return ret;
  }
  constexpr ModInt inv() const noexcept { return pow(mod - 2); }
  constexpr ModInt operator/=(const ModInt &rhs) {
    return (*this) *= rhs.inv();
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return this->a == rhs.a;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return this->a != rhs.a;
  }
  friend constexpr ostream &operator<<(ostream &os,
                                       const ModInt &rhs) noexcept {
    return os << rhs.a;
  }
  friend constexpr istream &operator>>(istream &is, ModInt &rhs) {
    is >> rhs.a;
    return is;
  }
};
using mint = ModInt<MOD>;

int main() {
  int n, s;
  cin >> n >> s;
  vector<int> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];

  // i個のxで和をjにするのは何通りあるか
  vector<vector<mint>> dp(n + 1, vector<mint>(s + 1));
  dp[0][0] = 1;
  for (int k = 0; k < n; k++) {
    for (int i = k; i >= 0; i--) {
      for (int j = 0; j + a[k] <= s; j++) {
        dp[i + 1][j + a[k]] += dp[i][j];
      }
    }
  }

  mint ans = 0;
  for (int i = 1; i <= n; i++) {
    mint tmp = 2;
    ans += tmp.pow(n - i) * dp[i][s];
  }

  cout << ans << endl;
  return 0;
}