Problem p02685 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; i++)
#define ll long long int
#define MAX 1000000007

using namespace std;

struct UnionFind {
  vector<int> par, num;

  UnionFind(int N) : par(N), num(N) {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      num[i] = 1;
    }
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry;
    num[ry] = num[ry] + num[rx];
  }

  int get_num(int x) {
    int rx = root(x);
    return num[rx];
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

ll modpow(ll a, ll n, ll p) {
  if (n == 0) {
    return 1;
  }
  if (n % 2 == 0) {
    ll root = modpow(a, n / 2, p);
    return (root * root + p) % p;
  } else {
    return (a * modpow(a, n - 1, p) + p) % p;
  }
}
ll fact[220000], fact_inv[220000];

ll comb(ll n, ll m, ll p) {
  return (fact[n] * fact_inv[m]) % p * fact_inv[n - m] % p;
}

int main(void) {
  int n, m, k;
  cin >> n >> m >> k;
  ll p = 998244353;

  fact[0] = 1;
  // 階乗の計算
  rep(i, n) fact[i + 1] = fact[i] * (i + 1) % p;
  fact_inv[n] = modpow(fact[n], p - 2, p);
  // 逆元の計算
  for (int i = n - 1; i >= 0; i--)
    fact_inv[i] = fact_inv[i + 1] * (i + 1) % p;

  ll ans = 0;
  for (int i = 0; i <= k; i++) {
    ll work = modpow(m - 1, n - 1 - i, p) * comb(n - 1, i, p);
    work %= p;
    ans += work;
    ans %= p;
  }
  ans = (ans * m) % p;

  cout << ans << endl;
  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; i++)
#define ll long long int
#define MAX 1000000007

using namespace std;

struct UnionFind {
  vector<int> par, num;

  UnionFind(int N) : par(N), num(N) {
    for (int i = 0; i < N; i++) {
      par[i] = i;
      num[i] = 1;
    }
  }

  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry;
    num[ry] = num[ry] + num[rx];
  }

  int get_num(int x) {
    int rx = root(x);
    return num[rx];
  }

  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

ll modpow(ll a, ll n, ll p) {
  if (n == 0) {
    return 1;
  }
  if (n % 2 == 0) {
    ll root = modpow(a, n / 2, p);
    return (root * root + p) % p;
  } else {
    return (a * modpow(a, n - 1, p) + p) % p;
  }
}
ll fact[300000], fact_inv[300000];

ll comb(ll n, ll m, ll p) {
  return (fact[n] * fact_inv[m]) % p * fact_inv[n - m] % p;
}
int main(void) {
  int n, m, k;
  cin >> n >> m >> k;
  ll p = 998244353;

  fact[0] = 1;
  // 階乗の計算
  rep(i, n) fact[i + 1] = fact[i] * (i + 1) % p;
  fact_inv[n] = modpow(fact[n], p - 2, p);
  // 逆元の計算
  for (int i = n - 1; i >= 0; i--)
    fact_inv[i] = fact_inv[i + 1] * (i + 1) % p;

  ll ans = 0;
  for (int i = 0; i <= k; i++) {
    // cout << ":::" << modpow(m-1,n-i,p) << "aaaa" << comb(n-i,i,p) << endl;
    ll work = modpow(m - 1, n - 1 - i, p) * comb(n - i, i, p) * m;
    work %= p;
    ans += work;
    ans %= p;
  }

  cout << ans << endl;
  return 0;
}