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

#include <iostream>
#define Z (2 << 17)
using namespace std;
const long mod = 998244353;
long power(long a, long b) {
  return b ? power(a * a % mod, b / 2) * (b % 2 ? a : 1) % mod : 1;
}
long fac[Z], inv[Z], ans, N, M, K;
int main() {
  fac[0] = 1;
  for (int i = 1; i < Z; i++)
    fac[i] = fac[i - 1] * i % mod;
  inv[(Z)-1] = power(fac[Z - 1], mod - 2);
  for (int i = Z - 1; i--;)
    inv[i] = inv[i + 1] * (i + 1) % mod;
  cin >> N >> M >> K;
  for (int L = 0; L <= K; L++)
    ans += fac[N - 1] * inv[N - 1 - L] % mod * inv[L] % mod * M % mod *
           power(M - 1, N - L - 1) % mod;
  cout << (ans % mod + mod) % mod << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <boost/multiprecision/cpp_int.hpp>
#include <cstdio>
#include <deque>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
using namespace boost::multiprecision;
using namespace std;
#define BEGIN                                                                  \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL)
#define END return EXIT_SUCCESS
#define up(I, A, B) for (auto I = (A); I <= (B); ++I)
#define dw(I, A, B) for (auto I = (A); I >= (B); --I)
#define rep(I, N) up(I, 0, N - 1)
#define all(C) (C).begin(), (C).end()
#define rall(C) (C).rbegin(), (C).rend()
#define ft first
#define sd second
#define mp make_pair
#define mt make_tuple
#define pf push_front
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define rs resize
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline void in(T &p) { cin >> p; }
template <class T1, class T2> inline void in(T1 &p1, T2 &p2) {
  cin >> p1 >> p2;
}
template <class T1, class T2, class T3> inline void in(T1 &p1, T2 &p2, T3 &p3) {
  cin >> p1 >> p2 >> p3;
}
template <class T1, class T2, class T3, class T4>
inline void in(T1 &p1, T2 &p2, T3 &p3, T4 &p4) {
  cin >> p1 >> p2 >> p3 >> p4;
}
template <class T1, class T2, class T3, class T4, class T5>
inline void in(T1 &p1, T2 &p2, T3 &p3, T4 &p4, T5 &p5) {
  cin >> p1 >> p2 >> p3 >> p4 >> p5;
}
template <class T> inline void ins(T &p) {
  for_each(all(p), in<decltype(p[0])>);
}
template <class T> inline void out(T p) { cout << p << "\\n"; }
template <class T1, class T2> inline void out(T1 p1, T2 p2) {
  cout << p1 << " " << p2 << "\\n";
}
template <class T1, class T2, class T3> inline void out(T1 p1, T2 p2, T3 p3) {
  cout << p1 << " " << p2 << " " << p3 << "\\n";
}
template <class T1, class T2, class T3, class T4>
inline void out(T1 p1, T2 p2, T3 p3, T4 p4) {
  cout << p1 << " " << p2 << " " << p3 << " " << p4 << "\\n";
}
inline void out(ld p) { printf("%.12Lf\\n", p); }
template <class T> inline void outml(T p) {
  for_each(all(p), out<decltype(p[0])>);
} // ml=multi line
template <class T> inline void outol(T V) {
  auto n = V.size();
  rep(i, n) cout << V[i] << " \\n"[i == n - 1];
} // ol=one line
class math {
private:
  long MOD;

public:
  math() { MOD = 1000000007; }
  math(long mod) { MOD = mod; }
  template <class T> inline T mod_add(T a, T b) {
    a %= MOD;
    a += b;
    if (a >= MOD)
      a -= MOD;
    return a;
  }
  template <class T> inline T mod_sub(T a, T b) {
    a %= MOD;
    a -= b;
    if (a < 0)
      a += MOD;
    return a;
  }
  template <class T> inline T mod_mul(T a, T b) {
    a %= MOD;
    a *= b;
    if (a >= MOD)
      a %= MOD;
    return a;
  }
  template <class T> inline T mod_div(T a, T b) {
    a %= MOD;
    a /= b;
    return a;
  }
  template <class T> inline T mod_pow(T a, T n) {
    T r = 1;
    while (n)
      r = r * ((n % 2) ? a : 1) % MOD, a = a * a % MOD, n >>= 1;
    return r;
  }
  template <class T> inline T nCr(T n, T r) {
    if (n < 0 || r < 0 || r > n)
      return 0;
    T p = 1, q = 1;
    r = min(r, n - r);
    for (T i = 1; i <= r; i++, n--)
      p = p * n % MOD, q = q * i % MOD;
    return p * mod_pow(q, MOD - 2) % MOD;
  }
  template <class T> inline T nHr(T n, T r) {
    return (n == 0 && r == 0) ? 1 : nCr(n + r - 1, r);
  }
  template <class T> inline map<T, T> prime_decomp(T n) {
    map<T, T> m;
    for (T i = 2; i * i <= n; i++) {
      while (n % i == 0) {
        m[i]++;
        n /= i;
      }
    }
    if (n > 1)
      m[n]++;
    return m;
  }
  template <class T> inline bool is_prime(T n) {
    if (n == 2)
      return true;
    if (n < 2 || n % 2 == 0)
      return false;
    for (T i = 3; i * i <= n; i += 2) {
      if (n % i == 0)
        return false;
    }
    return true;
  }
  template <class T> inline vector<T> divisor(T n) {
    vector<T> res;
    for (T i = 1; i * i <= n; i++) {
      if (n % i == 0) {
        res.push_back(i);
        if (i != n / i)
          res.push_back(n / i);
      }
    }
    return res;
  }
  template <class T> inline T calc_gcd(T a, T b) {
    if (b == 0)
      return a;
    return calc_gcd(b, a % b);
  }
  template <class T> inline T calc_lcm(T a, T b) {
    return a * b / calc_gcd(a, b);
  }
  template <class T> inline T fact(T n) {
    T res = 1;
    for (T i = 1; i <= n; i++)
      res *= i;
    return res;
  }
  template <class T> inline T sum(T n) { return n * (n + 1) / 2; }
  template <class T>
  inline bool ccw(T ax, T ay, T bx, T by, T cx, T cy, T dx, T dy) {
    T ta = (cx - dx) * (ay - cy) + (cy - dy) * (cx - ax);
    T tb = (cx - dx) * (by - cy) + (cy - dy) * (cx - bx);
    T tc = (ax - bx) * (cy - ay) + (ay - by) * (ax - cx);
    T td = (ax - bx) * (dy - ay) + (ay - by) * (ax - dx);
    return tc * td < 0 && ta * tb < 0; // 端点を含まない場合
    // return tc * td <= 0 && ta * tb <= 0; // 端点を含む場合
  }
} math(998244353);
long n, m, k, ans, mod = 998244353;
inline void solve(void) {
  in(n, m, k);
  rep(i, k + 1) {
    ans += math.nCr(n - 1, (long)i) % mod * m % mod *
           math.mod_pow(m - 1, n - i - 1) % mod;
  }
  out((ans % mod + mod) % mod);
}
int main(void) {
  BEGIN;
  solve();
  END;
}