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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define irep(i, a, b) for (typeof(i) i = (a); i < (b); ++i)
#define itrep(it, c) for (auto it = (c).begin(); it != (c).end(); ++it)

// MOD p でいくつクラス
#define MOD 998244353
class mll {
  unsigned long long val = 0;

public:
  mll(long long y = 0) : val(((y % MOD) + MOD) % MOD) {}
  mll operator+(const mll &y) { return mll(*this) += y; }
  mll &operator+=(const mll &y) {
    val = (val + y.val) % MOD;
    return *this;
  }
  mll operator-(const mll &y) { return mll(*this) -= y; }
  mll &operator-=(const mll &y) {
    val = (val - y.val + MOD) % MOD;
    return *this;
  }
  mll operator*(const mll &y) { return mll(*this) *= y; }
  mll &operator*=(const mll &y) {
    val = (val * y.val) % MOD;
    return *this;
  }
  mll operator/(const mll &y) { return mll(*this) /= y; }
  mll &operator/=(const mll &y) {
    long long a = y.val, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    mll c = val * u; // この計算でoverflowしないか？
    val = c.val;
    return *this;
  }
  bool operator>=(const mll &y) { return this->val >= y.val; }
  mll pow(long long t) const {
    if (!t)
      return 1;
    mll a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
  unsigned long long getVal() { return val; }
  friend ostream &operator<<(ostream &os, mll &y) {
    os << y.val;
    return os;
  }
};
#undef MOD

vector<int> A;
vector<vector<mll>> dp;
vector<vector<bool>> F;

void ask(int i, int j) { // dp[i][j] をセットする。し終わったらreturn
  if (F[i][j])
    return;
  ask(i - 1, j);
  dp[i][j] = dp[i - 1][j];
  if (j >= A[i - 1]) {
    ask(i - 1, j - A[i - 1]);
    dp[i][j] += dp[i - 1][j - A[i - 1]] / 2;
  }
  F[i][j] = true;
  return;
}

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

  int N, S;
  cin >> N >> S;
  A = vector<int>(N, 0);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  sort(A.begin(), A.end());
  dp = vector<vector<mll>>(N + 1, vector<mll>(S + 1, 0));
  F = vector<vector<bool>>(N + 1, vector<bool>(S + 1, false));

  // i = 0;
  dp[0][0] =
      mll(2).pow(N); // dp[0][0] には、(0個,1ケース)を入れる。dp[0][j>0] はempty
  for (int j = 0; j <= S; j++) {
    F[0][j] = true;
  }
  // DP
  ask(N, S);

  cout << dp[N][S].getVal() << endl;
  return (0);
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define irep(i, a, b) for (typeof(i) i = (a); i < (b); ++i)
#define itrep(it, c) for (auto it = (c).begin(); it != (c).end(); ++it)

// MOD p でいくつクラス
#define MOD 998244353
class mll {
  unsigned long long val = 0;

public:
  mll(long long y = 0) : val(((y % MOD) + MOD) % MOD) {}
  mll operator+(const mll &y) { return mll(*this) += y; }
  mll &operator+=(const mll &y) {
    val = (val + y.val) % MOD;
    return *this;
  }
  mll operator-(const mll &y) { return mll(*this) -= y; }
  mll &operator-=(const mll &y) {
    val = (val - y.val + MOD) % MOD;
    return *this;
  }
  mll operator*(const mll &y) { return mll(*this) *= y; }
  mll &operator*=(const mll &y) {
    val = (val * y.val) % MOD;
    return *this;
  }
  mll operator/(const mll &y) { return mll(*this) /= y; }
  mll &operator/=(const mll &y) {
    long long a = y.val, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    mll c = val * u; // この計算でoverflowしないか？
    val = c.val;
    return *this;
  }
  bool operator>=(const mll &y) { return this->val >= y.val; }
  mll pow(long long t) const {
    if (!t)
      return 1;
    mll a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
  unsigned long long getVal() { return val; }
  friend ostream &operator<<(ostream &os, mll &y) {
    os << y.val;
    return os;
  }
};
#undef MOD

vector<int> A;
vector<vector<map<int, mll>>> dp;
vector<vector<bool>> F;

void ask(int i, int j) { // dp[i][j] をセットする。し終わったらreturn
  if (F[i][j])
    return;
  ask(i - 1, j);
  dp[i][j] = dp[i - 1][j];
  if (j >= A[i - 1]) {
    ask(i - 1, j - A[i - 1]);
    for (auto it = dp[i - 1][j - A[i - 1]].begin();
         it != dp[i - 1][j - A[i - 1]].end(); it++) {
      dp[i][j][it->first + 1] += it->second;
    }
  }
  F[i][j] = true;
  return;
}

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

  int N, S;
  cin >> N >> S;
  A = vector<int>(N, 0);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  sort(A.begin(), A.end());
  dp = vector<vector<map<int, mll>>>(N + 1, vector<map<int, mll>>(S + 1));
  F = vector<vector<bool>>(N + 1, vector<bool>(S + 1, false));

  // i = 0;
  dp[0][0][0] = 1; // dp[0][0] には、(0個,1ケース)を入れる。dp[0][j>0] はempty
  for (int j = 0; j <= S; j++) {
    F[0][j] = true;
  }
  // DP
  ask(N, S);

  // 積算
  mll count = 0;
  for (auto it = dp[N][S].begin(); it != dp[N][S].end(); it++) {
    count += it->second * mll(2).pow(N - it->first);
  }

  cout << count.getVal() << endl;
  return (0);
}