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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef unsigned long long ll;
#define mod 998244353

int64_t power(int64_t n, int64_t k, ll p) {
  if (k == 0)
    return 1;
  int64_t ans = power(n * n % p, k / 2, p);
  if (k % 2) {
    ans = ans * n % p;
  }
  return ans;
}

ll modInverse(ll a, ll p) { return power(a, p - 2, p); }

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  ll n, m, k;
  cin >> n >> m >> k;

  ll ans = 0;
  ll val_1 = 1;
  vector<ll> po(k + 1, 0);
  po[0] = power(m - 1, n - k - 1, mod);
  for (ll i = 1; i <= k; i++) {
    po[i] = po[i - 1] * (m - 1) % mod;
  }

  for (ll i = 0; i <= k; i++) {
    ll val = val_1 * m % mod;
    val = val * po[k - i] % mod;
    ans += val;
    ans %= mod;
    val_1 = val_1 * (n - 1 - i) % mod;
    val_1 = val_1 * modInverse(i + 1, mod) % mod;
  }
  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef unsigned long long ll;
#define mod 998244353

ll nCrModpDP(ll n, ll r) {
  // The array C is going to store last row of
  // pascal triangle at the end. And last entry
  // of last row is nCr
  ll C[r + 1];
  memset(C, 0, sizeof(C));

  C[0] = 1; // Top row of Pascal Triangle

  // One by constructs remaining rows of Pascal
  // Triangle from top to bottom
  for (ll i = 1; i <= n; i++) {
    // Fill entries of current row using previous
    // row values
    for (ll j = min(i, r); j > 0; j--)

      // nCj = (n-1)Cj + (n-1)C(j-1);
      C[j] = (C[j] + C[j - 1]) % mod;
  }
  return C[r];
}

// Lucas Theorem based function that returns nCr % p
// This function works like decimal to binary conversion
// recursive function.  First we compute last digits of
// n and r in base p, then recur for remaining digits
ll choose(ll n, ll r) {
  // Base case
  if (r == 0)
    return 1;

  // Compute last digits of n and r in base p
  ll ni = n % mod, ri = r % mod;

  // Compute result for last digits computed above, and
  // for remaining digits.  Multiply the two results and
  // compute the result of multiplication in modulo p.
  return (choose(n / mod, r / mod) * // Last digits of n and r
          nCrModpDP(ni, ri)) %
         mod; // Remaining digits
}

int64_t power(int64_t n, int64_t k) {
  if (k == 0)
    return 1;
  int64_t ans = power(n * n % mod, k / 2);
  if (k % 2) {
    ans = ans * n % mod;
  }
  return ans;
}

int main() {
  ll n, m, k;
  cin >> n >> m >> k;

  ll ans = 0;
  //    ll val_1 = 1;
  vector<ll> po(k + 1, 0);
  po[0] = power(m - 1, n - k - 1);
  for (ll i = 1; i <= k; i++) {
    po[i] = po[i - 1] * (m - 1) % mod;
  }

  for (ll i = 0; i <= k; i++) {
    ll val = choose(n - 1, i) * m % mod;
    val = val * po[k - i] % mod;
    ans += val;
    ans %= mod;

    //        val_1 = val_1*(n-1-i)%mod;
    //        ///(i+1)
    //        if(val_1%(i+1)!=0){
    //            cout<<"hi"<<endl;
    //        }
    //        val_1 = val_1/(i+1);
    //        val_1%=mod;
  }
  cout << ans << endl;

  return 0;
}