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

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 998244353;
const ll LINF = 1e18;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T> ostream &operator<<(ostream &os, vector<T> v) {
  for (int i = 0; i < sz(v); i++) {
    os << v[i];
    if (i < sz(v) - 1)
      os << " ";
  }
  return os;
}
struct modint {
  ll x;
  modint(ll x = 0) : x((x % MOD + MOD) % MOD) {}
  ll value() const { return x; }
  modint operator-() const { return modint(-x); }
  modint &operator+=(const modint a) {
    if ((x += a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  modint &operator-=(const modint a) {
    if ((x += MOD - a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  modint &operator*=(const modint a) {
    (x *= a.x) %= MOD;
    return *this;
  }
  modint operator+(const modint a) const {
    modint res(*this);
    return res += a;
  }
  modint operator-(const modint a) const {
    modint res(*this);
    return res -= a;
  }
  modint operator*(const modint a) const {
    modint res(*this);
    return res *= a;
  }
  modint pow(ll t) const {
    if (t == 0)
      return 1;
    modint a = pow(t >> 1);
    a *= a;
    if (t % 2 == 1)
      a *= *this;
    return a;
  }
  modint inv() const { return pow(MOD - 2); }
  modint &operator/=(const modint a) { return (*this) *= a.inv(); }
  modint operator/(const modint a) const {
    modint res(*this);
    return res /= a;
  }
};
ostream &operator<<(ostream &os, const modint &x) {
  os << x.value();
  return os;
}
struct combination {
  vector<modint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < MOD);
    fact[0] = 1;
    for (int i = 1; i <= n; i++) {
      fact[i] = fact[i - 1] * i;
    }
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; i--) {
      ifact[i - 1] = ifact[i] * i;
    }
  }
  modint operator()(int n, int k) {
    if (n < k || k < 0)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
  modint h(int n, int k) {
    n += k - 1;
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
} comb(2002002);
int main() {
  int n, s;
  cin >> n >> s;
  vector<int> a(n);
  rep(i, n) cin >> a[i];
  auto dp = make_vec<modint>(3030, 3030);
  dp[0][0] = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 3030; j++) {
      dp[i + 1][j] += dp[i][j] * 2;
      if (j + a[i] < 3030)
        dp[i + 1][j + a[i]] += dp[i][j];
    }
  }
  cout << dp[n][s] << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 998244353;
const ll LINF = 1e18;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> vector<T> make_vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto make_vec(size_t a, Ts... ts) {
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T> ostream &operator<<(ostream &os, vector<T> v) {
  for (int i = 0; i < sz(v); i++) {
    os << v[i];
    if (i < sz(v) - 1)
      os << " ";
  }
  return os;
}
struct NumberTheoreticTransform {
  ll ext_gxd(ll a, ll b, ll &x, ll &y) {
    if (b == 0) {
      x = 1;
      y = 0;
      return a;
    }
    ll q = a / b;
    ll g = ext_gxd(b, a - q * b, x, y);
    ll z = x - q * y;
    x = y;
    y = z;
    return g;
  }

  ll MODinv(ll a, ll m) {
    ll x, y;
    ext_gxd(a, m, x, y);
    x %= m;
    if (x < 0)
      x += m;
    return x;
  }

  ll MODpow(ll a, ll n, ll m) {
    ll ret = 1;
    ll now = a;
    while (n > 0) {
      if (n % 2 == 1)
        ret = ret * now % m;
      now = now * now % m;
      n /= 2;
    }
    return ret;
  }

  void ntt(vector<ll> &a, bool inv = 0) {
    const int n = sz(a);
    assert((n & (n - 1)) == 0);

    const ll g = 3;
    ll h = MODpow(g, (MOD - 1) / n, MOD);
    if (inv)
      h = MODinv(h, MOD);

    int i = 0;
    for (int j = 1; j < n - 1; j++) {
      for (int k = n >> 1; k > (i ^= k); k >>= 1) {
      };
      if (j < i)
        swap(a[i], a[j]);
    }

    for (int m = 1; m < n; m *= 2) {
      const int m2 = m * 2;
      const ll base = MODpow(h, n / m2, MOD);
      ll w = 1;
      for (int x = 0; x < m; x++) {
        for (int s = x; s < n; s += m2) {
          ll u = a[s];
          ll d = a[s + m] * w % MOD;
          a[s] = u + d;
          if (a[s] >= MOD)
            a[s] -= MOD;
          a[s + m] = u - d;
          if (a[s + m] < 0)
            a[s + m] += MOD;
        }
        w = w * base % MOD;
      }
    }

    for (auto &x : a) {
      if (x < 0)
        x += MOD;
    }

    if (inv) {
      const int n_inv = MODinv(n, MOD);
      for (auto &x : a)
        x = x * n_inv % MOD;
    }
  }

  vector<ll> convolution(const vector<ll> &a, vector<ll> &b) {
    int ntt_size = 1;
    while (ntt_size < sz(a) + sz(b))
      ntt_size <<= 1;

    vector<ll> _a = a, _b = b;
    _a.resize(ntt_size);
    _b.resize(ntt_size);

    ntt(_a, 0);
    ntt(_b, 0);

    for (int i = 0; i < ntt_size; i++) {
      _a[i] *= _b[i];
      _a[i] %= MOD;
    }

    ntt(_a, 1);
    return _a;
  }
} ntt;
int main() {
  int n, s;
  cin >> n >> s;
  vector<vector<ll>> f(n);
  rep(i, n) {
    int a;
    cin >> a;
    f[i].resize(3030);
    f[i][0] = 2;
    f[i][a] = 1;
  }
  vector<ll> g(3030);
  g[0] = 1;
  rep(i, n) {
    g = ntt.convolution(g, f[i]);
    g.resize(3030);
  }
  cout << g[s] << endl;
}