Problem p03082 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

#define vi std::vector<int>
#define vvi std::vector<std::vector<int>>
#define vpi std::vector<pi>
#define pi std::pair<int, int>
#define fi first
#define se second
#define all(n) n.begin(), n.end()

#define FROMTO(var, from, to)                                                  \
  for (int var = (from), var##down = ((int)(to)) < ((int)(from));              \
       var##down ? (var >= (int)(to)) : (var <= (int)(to));                    \
       var##down ? var-- : var++)
#define UPTO(var, from, to) for (int var = (from); var <= ((int)(to)); var++)
#define DOWNTO(var, from, to) for (int var = (from); var >= ((int)(to)); var--)
#define FOR(var, to) UPTO(var, 0, (to)-1)
#define DOWN(var, from) DOWNTO(var, (from)-1, 0)

#define INIT(var, val) FOR(i, countof(var)) var[i] = val
#define INPUT(var) FOR(i, countof(var)) cin >> var[i]
#define INPUT1(var) FOR(i, countof(var)) cin >> var[i], var[i]--

#define SORT(v) qsort(v, countof(v), sizeof(*v), int_less)
#define SORTT(v) qsort(v, countof(v), sizeof(*v), int_greater)
#define QSORT(v, b) qsort(v, countof(v), sizeof(*v), b)

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

static const int MOD = 1000000007;
static const int INF = ((1 << 30) - 1);
static const s64 LINF = ((1LL << 62) - 1);

struct Comb {
  std::vector<std::vector<s64>> a;
  Comb(int n) { // O(n^2)
    a.resize(n + 1);
    FOR(i, n + 1) {
      a[i].resize(i + 1, 1);
      UPTO(j, 1, i - 1) a[i][j] = a[i - 1][j] + a[i - 1][j];
    }
  }
  s64 ncr(int n, int r) {
    assert(n >= 0);
    assert(n <= (int)a.size());
    assert(r >= 0);
    assert(r <= n);
    return a[n][r];
  }
};

#define gc(c) (c) = getchar()
int ri() {
  int c, s = 0, r = 0;
  for (;;) {
    gc(c);
    if (c == '-') {
      s = 1;
      break;
    }
    if (c >= '0' && c <= '9') {
      r = c - '0';
      break;
    }
  }
  for (;;) {
    gc(c);
    if (c < '0' || c > '9')
      break;
    r *= 10;
    r += c - '0';
  }
  if (s)
    r = -r;
  return r;
}
s64 rs64() {
  s64 r;
  int c, s;
  for (;;) {
    gc(c);
    if (c == '-') {
      s = 1;
      break;
    }
    if (c >= '0' && c <= '9') {
      r = c - '0';
      break;
    }
  }
  for (;;) {
    gc(c);
    if (c < '0' || c > '9')
      break;
    r *= 10;
    r += c - '0';
  }
  if (s)
    r = -r;
  return r;
}

int int_less(const void *a, const void *b) {
  return (*(const int *)a - *(const int *)b);
}
int int_greater(const void *a, const void *b) {
  return (*(const int *)b - *(const int *)a);
}
std::string operator*(const std::string &s, int n) {
  std::string res;
  FOR(i, n) res += s;
  return res;
}

template <class T>
std::ostream &operator<<(std::ostream &os, std::vector<T> a) {
  for (auto i : a)
    os << i << " ";
  return os;
}
template <class T> std::ostream &operator<<(std::ostream &os, std::set<T> a) {
  for (auto i : a)
    os << i << " ";
  return os;
}
template <class A, class B>
std::ostream &operator<<(std::ostream &os, std::pair<A, B> a) {
  os << a.fi << "," << a.se;
  return os;
}

template <int mod> struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
  ModInt operator-() const { return ModInt(-x); }
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
  bool operator==(const ModInt &p) const { return x == p.x; }
  bool operator!=(const ModInt &p) const { return x != p.x; }
  explicit operator int() const { return x; } // added by QCFium
  ModInt operator=(const int p) {
    x = p;
    return ModInt(*this);
  } // added by QCFium
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    return ModInt(u);
  }
  friend std::ostream &operator<<(std::ostream &os, const ModInt<mod> &p) {
    return os << p.x;
  }
  friend std::istream &operator>>(std::istream &is, ModInt<mod> &a) {
    long long x;
    is >> x;
    a = ModInt<mod>(x);
    return (is);
  }
};
typedef ModInt<MOD> mint;

mint mpow(s64 num, s64 times) { // O(log(times))
  mint next = num % MOD;
  mint res = 1;
  while (times) {
    if (times % 2)
      res *= next;
    next *= next;
    times /= 2;
  }
  return res;
}

struct MComb {
  std::vector<mint> fact;
  std::vector<mint> inversed;
  MComb(int n) { // O(n+log(mod))
    fact = std::vector<mint>(n + 1, 1);
    UPTO(i, 1, n) fact[i] = fact[i - 1] * mint(i);
    inversed = std::vector<mint>(n + 1);
    inversed[n] = mpow((int)fact[n], MOD - 2);
    DOWN(i, n) inversed[i] = inversed[i + 1] * mint(i + 1);
  }

  mint ncr(int n, int r) { return (fact[n] * inversed[r] * inversed[n - r]); }

  mint npr(int n, int r) { return (fact[n] * inversed[n - r]); }

  mint nhr(int n, int r) {
    assert(n + r - 1 < (int)fact.size());
    return ncr(n + r - 1, r);
  }
};

int n;
std::vector<int> a;
std::vector<std::vector<mint>> memo;
std::vector<std::vector<bool>> ava;
mint dfs(int left, int cur) {
  if (!left)
    return cur;
  if (ava[left][cur])
    return memo[left][cur];
  mint res = 0;
  // use a[left - 1] as first
  res += dfs(left - 1, cur % a[left - 1]);
  // don't use a[left - 1] as first(throw everywhere)
  if (left > 1)
    res += dfs(left - 1, cur) * (left - 1);
  return memo[left][cur] = res;
}

int main() {
  n = ri();
  int x = ri();
  a.resize(n);
  FOR(i, n) a[i] = ri();
  sort(a.begin(), a.end(), std::less<int>());
  ava.resize(n + 1, std::vector<bool>(x + 1, false));
  memo.resize(n + 1, std::vector<mint>(x + 1, 0));
  std::cout << dfs(n, x) << std::endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

#define vi std::vector<int>
#define vvi std::vector<std::vector<int>>
#define vpi std::vector<pi>
#define pi std::pair<int, int>
#define fi first
#define se second
#define all(n) n.begin(), n.end()

#define FROMTO(var, from, to)                                                  \
  for (int var = (from), var##down = ((int)(to)) < ((int)(from));              \
       var##down ? (var >= (int)(to)) : (var <= (int)(to));                    \
       var##down ? var-- : var++)
#define UPTO(var, from, to) for (int var = (from); var <= ((int)(to)); var++)
#define DOWNTO(var, from, to) for (int var = (from); var >= ((int)(to)); var--)
#define FOR(var, to) UPTO(var, 0, (to)-1)
#define DOWN(var, from) DOWNTO(var, (from)-1, 0)

#define INIT(var, val) FOR(i, countof(var)) var[i] = val
#define INPUT(var) FOR(i, countof(var)) cin >> var[i]
#define INPUT1(var) FOR(i, countof(var)) cin >> var[i], var[i]--

#define SORT(v) qsort(v, countof(v), sizeof(*v), int_less)
#define SORTT(v) qsort(v, countof(v), sizeof(*v), int_greater)
#define QSORT(v, b) qsort(v, countof(v), sizeof(*v), b)

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

static const int MOD = 1000000007;
static const int INF = ((1 << 30) - 1);
static const s64 LINF = ((1LL << 62) - 1);

struct Comb {
  std::vector<std::vector<s64>> a;
  Comb(int n) { // O(n^2)
    a.resize(n + 1);
    FOR(i, n + 1) {
      a[i].resize(i + 1, 1);
      UPTO(j, 1, i - 1) a[i][j] = a[i - 1][j] + a[i - 1][j];
    }
  }
  s64 ncr(int n, int r) {
    assert(n >= 0);
    assert(n <= (int)a.size());
    assert(r >= 0);
    assert(r <= n);
    return a[n][r];
  }
};

#define gc(c) (c) = getchar()
int ri() {
  int c, s = 0, r = 0;
  for (;;) {
    gc(c);
    if (c == '-') {
      s = 1;
      break;
    }
    if (c >= '0' && c <= '9') {
      r = c - '0';
      break;
    }
  }
  for (;;) {
    gc(c);
    if (c < '0' || c > '9')
      break;
    r *= 10;
    r += c - '0';
  }
  if (s)
    r = -r;
  return r;
}
s64 rs64() {
  s64 r;
  int c, s;
  for (;;) {
    gc(c);
    if (c == '-') {
      s = 1;
      break;
    }
    if (c >= '0' && c <= '9') {
      r = c - '0';
      break;
    }
  }
  for (;;) {
    gc(c);
    if (c < '0' || c > '9')
      break;
    r *= 10;
    r += c - '0';
  }
  if (s)
    r = -r;
  return r;
}

int int_less(const void *a, const void *b) {
  return (*(const int *)a - *(const int *)b);
}
int int_greater(const void *a, const void *b) {
  return (*(const int *)b - *(const int *)a);
}
std::string operator*(const std::string &s, int n) {
  std::string res;
  FOR(i, n) res += s;
  return res;
}

template <class T>
std::ostream &operator<<(std::ostream &os, std::vector<T> a) {
  for (auto i : a)
    os << i << " ";
  return os;
}
template <class T> std::ostream &operator<<(std::ostream &os, std::set<T> a) {
  for (auto i : a)
    os << i << " ";
  return os;
}
template <class A, class B>
std::ostream &operator<<(std::ostream &os, std::pair<A, B> a) {
  os << a.fi << "," << a.se;
  return os;
}

template <int mod> struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
  ModInt operator-() const { return ModInt(-x); }
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
  bool operator==(const ModInt &p) const { return x == p.x; }
  bool operator!=(const ModInt &p) const { return x != p.x; }
  explicit operator int() const { return x; } // added by QCFium
  ModInt operator=(const int p) {
    x = p;
    return ModInt(*this);
  } // added by QCFium
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    return ModInt(u);
  }
  friend std::ostream &operator<<(std::ostream &os, const ModInt<mod> &p) {
    return os << p.x;
  }
  friend std::istream &operator>>(std::istream &is, ModInt<mod> &a) {
    long long x;
    is >> x;
    a = ModInt<mod>(x);
    return (is);
  }
};
typedef ModInt<MOD> mint;

mint mpow(s64 num, s64 times) { // O(log(times))
  mint next = num % MOD;
  mint res = 1;
  while (times) {
    if (times % 2)
      res *= next;
    next *= next;
    times /= 2;
  }
  return res;
}

struct MComb {
  std::vector<mint> fact;
  std::vector<mint> inversed;
  MComb(int n) { // O(n+log(mod))
    fact = std::vector<mint>(n + 1, 1);
    UPTO(i, 1, n) fact[i] = fact[i - 1] * mint(i);
    inversed = std::vector<mint>(n + 1);
    inversed[n] = mpow((int)fact[n], MOD - 2);
    DOWN(i, n) inversed[i] = inversed[i + 1] * mint(i + 1);
  }

  mint ncr(int n, int r) { return (fact[n] * inversed[r] * inversed[n - r]); }

  mint npr(int n, int r) { return (fact[n] * inversed[n - r]); }

  mint nhr(int n, int r) {
    assert(n + r - 1 < (int)fact.size());
    return ncr(n + r - 1, r);
  }
};

int n;
std::vector<int> a;
std::vector<std::vector<mint>> memo;
std::vector<std::vector<bool>> ava;
mint dfs(int left, int cur) {
  if (!left)
    return cur;
  if (ava[left][cur])
    return memo[left][cur];
  mint res = 0;
  // use a[left - 1] as first
  res += dfs(left - 1, cur % a[left - 1]);
  // don't use a[left - 1] as first(throw everywhere)
  if (left > 1)
    res += dfs(left - 1, cur) * (left - 1);
  ava[left][cur] = true;
  return memo[left][cur] = res;
}

int main() {
  n = ri();
  int x = ri();
  a.resize(n);
  FOR(i, n) a[i] = ri();
  sort(a.begin(), a.end(), std::less<int>());
  ava.resize(n + 1, std::vector<bool>(x + 1, false));
  memo.resize(n + 1, std::vector<mint>(x + 1, 0));
  std::cout << dfs(n, x) << std::endl;
  return 0;
}