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

#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
typedef long long ll;
typedef unsigned long long ull;

static const long long mod = 1000000007;
struct mint {
  long long x;
  mint(ll x = 0) : x(x % mod) {}
  mint &operator+=(const mint a) {
    (x += a.x) %= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    (x += mod - a.x) %= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint ret(*this);
    return ret += a;
  }
  mint operator-(const mint a) const {
    mint ret(*this);
    return ret -= a;
  }
  mint operator*(const mint a) const {
    mint ret(*this);
    return ret *= a;
  }
  mint pow(ll t) const {
    if (t == 0)
      return mint(1);
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint ret(*this);
    return ret /= a;
  }
};
ostream &operator<<(ostream &os, const mint &x) {
  os << x.x;
  return os;
}
class modutils {
  vector<mint> fact, invfact;

public:
  modutils(int n = 2000005) : fact(n + 1), invfact(n + 1) {
    fact[0] = 1;
    for (int i = 1; i <= n; i++)
      fact[i] = fact[i - 1] * i;
    invfact[n] = fact[n].inv();
    for (int i = n; i >= 1; i--)
      invfact[i - 1] = invfact[i] * i;
  }
  mint pow(mint x, ll n) { return x.pow(n); }
  mint comb(ll n, ll k) {
    if (n < 0 || k < 0 || n < k)
      return 0;
    return fact[n] * invfact[k] * invfact[n - k];
  }
  mint perm(ll n, ll k) {
    if (n < 0 || k < 0 || n < k)
      return 0;
    return fact[n] * invfact[n - k];
  }
  mint fac(ll n) { return fact[n]; }
};
modutils mutil;

int main() {
  ll N, M;
  cin >> N >> M;

  mint ret = mutil.perm(M, N);

  REP(i, 1, N + 1) {
    if (i % 2 == 1) {
      ret -= mutil.comb(N, i) * mutil.perm(M - i, N - i);
    } else {
      ret += mutil.comb(N, i) * mutil.perm(M - i, N - i);
    }
  }

  ret *= mutil.perm(M, N);

  cout << ret << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
typedef long long ll;
typedef unsigned long long ull;

static const long long mod = 1000000007;
struct mint {
  long long x;
  mint(ll x = 0) : x(x % mod) {}
  mint &operator+=(const mint a) {
    (x += a.x) %= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    (x += mod - a.x) %= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint ret(*this);
    return ret += a;
  }
  mint operator-(const mint a) const {
    mint ret(*this);
    return ret -= a;
  }
  mint operator*(const mint a) const {
    mint ret(*this);
    return ret *= a;
  }
  mint pow(ll t) const {
    if (t == 0)
      return mint(1);
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint ret(*this);
    return ret /= a;
  }
};
ostream &operator<<(ostream &os, const mint &x) {
  os << x.x;
  return os;
}
class modutils {
  vector<mint> fact, invfact;

public:
  modutils(int n = 2000005) : fact(n + 1), invfact(n + 1) {
    fact[0] = 1;
    for (int i = 1; i <= n; i++)
      fact[i] = fact[i - 1] * i;
    invfact[n] = fact[n].inv();
    for (int i = n; i >= 1; i--)
      invfact[i - 1] = invfact[i] * i;
  }
  mint pow(mint x, ll n) { return x.pow(n); }
  mint comb(ll n, ll k) {
    if (n < 0 || k < 0 || n < k)
      return 0;
    return fact[n] * invfact[k] * invfact[n - k];
  }
  mint perm(ll n, ll k) {
    if (n < 0 || k < 0 || n < k)
      return 0;
    return fact[n] * invfact[n - k];
  }
  mint fac(ll n) { return fact[n]; }
};
modutils mutil;

namespace std {
template <> class hash<std::pair<ll, ll>> {
public:
  size_t operator()(const std::pair<ll, ll> &x) const {
    return hash<ll>()(x.first) ^ hash<ll>()(x.second);
  }
};
} // namespace std

unordered_map<pair<ll, ll>, mint> memo;

mint solve(ll N, ll M) {
  if (N <= 0 || M <= 0)
    return mint(1);
  if (memo.count(make_pair(N, M)) > 0)
    return memo[make_pair(N, M)];
  mint ret = mutil.perm(M, N);
  ret -= 1;
  REP(i, 1, N) {
    mint tmp = mutil.comb(N, i);
    tmp *= solve(N - 1, M - 1);
    ret -= tmp;
  }
  return memo[make_pair(N, M)] = ret;
}

int main() {
  ll N, M;
  cin >> N >> M;

  cout << mutil.perm(M, N) * solve(N, M) << endl;

  return 0;
}