Problem:
Problem H: Count Words
Problem
$M$ 種類の文字がある。それらを使って長さ $N$ の文字列を作る。使われている文字の種類数が $K$ 以上であるような文字列は何通りあるか。$998244353$ で割ったあまりを求めよ。
ここで長さ $N$ の2つの文字列が異なるとは以下のように定義される。
2つの文字列を $S = S_1S_2 \ldots S_N$, $T = T_1T_2 \ldots T_N$ とした場合に、$S_i \neq T_i$ となるような $i$ $(1 \leq i \leq N)$ が存在する。
Input
入力は以下の形式で与えられる。
$M$ $N$ $K$
1行に $M, N, K$ が空白区切りで与えられる。
Constraints
入力は以下の条件を満たす。
$1 \leq M \leq 10^{18} $
$1 \leq N \leq 10^{18} $
$1 \leq K \leq 1000 $
入力はすべて整数
Output
使われている文字の種類数が $K$ 以上であるような長さ $N$ の文字列の通り数を $998244353$ で割ったあまりを出力せよ。
Sample Input 1
2 10 1
Sample Output 1
1024
Sample Input 2
1 1 2
Sample Output 2
0
Sample Input 3
5 10 3
Sample Output 3
9755400
Sample Input 4
7 8 3
Sample Output 4
5759460
Sample Input 5
1000000000000000000 1000000000000000000 1000
Sample Output 5
133611974

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

long long mod = 998244353;

long long binpow(long long aa, long long nn, long long mod) {
	if (nn == 0) return 1ll;
	if (nn % 2 == 1)
		return (binpow(aa, nn - 1, mod) * (aa % mod)) % mod;
	else {
		long long bb = binpow(aa, nn / 2, mod);
		return (bb * bb) % mod;
	}
}

long long cnt[1100];

const int maxn = 1100;
long long C[maxn + 1][maxn + 1];
void comb(long long mod)
{
	for (int nn = 0; nn <= maxn; ++nn) {
		C[nn][0] = C[nn][nn] = 1;
		for (int kk = 1; kk < nn; ++kk)
			C[nn][kk] = (C[nn - 1][kk - 1] + C[nn - 1][kk]) % mod;
	}
}


int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long m, n, k;
    cin >> m >> n >> k;

    long long total = binpow(m, n, mod);

    auto CC = [&](long long kk)
    {
        long long num = 1ll;
        for (long long i = m - kk + 1; i <= m; ++i) {
            num *= i % mod;
            num %= mod;
        }
        long long denom = 1ll;
        for (long long i = 1; i <= kk; ++i) {
            denom *= i % mod;
            denom %= mod;
        }
        long long res = num * binpow(denom, mod - 2, mod) % mod;
        return res;
    };

    comb(mod);

    memset(cnt, 0, sizeof(cnt));
    long long sum = 0;
    for (int i = 1; i <= k - 1; ++i) {
        long long cur = 0;
        long long x = i;
        long long sign = 1;
        while(x)
        {
            cur += ((sign * binpow(x, n, mod) * C[i][x]) % mod + mod) % mod;
            cur %= mod;
            sign *= -1ll;
            x--;
        }
        cnt[i] = CC(i) * cur % mod;
        sum += cnt[i];
        sum %= mod;
    }

    long long res = ((total - sum) % mod + mod) % mod;
    cout << res << endl;


    return 0;
}
accuracy: 1
time_ms: 550
memory_kb: 12060
final_rank: 18

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 998244353;
constexpr int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
constexpr int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

template <int M>
struct MInt {
  unsigned int val;
  MInt(): val(0) {}
  MInt(long long x) : val(x >= 0 ? x % M : x % M + M) {}
  static constexpr int get_mod() { return M; }
  static void set_mod(int divisor) { assert(divisor == M); }
  static void init(int x = 10000000) { inv(x, true); fact(x); fact_inv(x); }
  static MInt inv(int x, bool init = false) {
    // assert(0 <= x && x < M && std::__gcd(x, M) == 1);
    static std::vector<MInt> inverse{0, 1};
    int prev = inverse.size();
    if (init && x >= prev) {
      // "x!" and "M" must be disjoint.
      inverse.resize(x + 1);
      for (int i = prev; i <= x; ++i) inverse[i] = -inverse[M % i] * (M / i);
    }
    if (x < inverse.size()) return inverse[x];
    unsigned int a = x, b = M; int u = 1, v = 0;
    while (b) {
      unsigned int tmp = a / b;
      std::swap(a -= tmp * b, b);
      std::swap(u -= tmp * v, v);
    }
    return u;
  }
  static MInt fact(int x) {
    static std::vector<MInt> f{1};
    int prev = f.size();
    if (x >= prev) {
      f.resize(x + 1);
      for (int i = prev; i <= x; ++i) f[i] = f[i - 1] * i;
    }
    return f[x];
  }
  static MInt fact_inv(int x) {
    static std::vector<MInt> finv{1};
    int prev = finv.size();
    if (x >= prev) {
      finv.resize(x + 1);
      finv[x] = inv(fact(x).val);
      for (int i = x; i > prev; --i) finv[i - 1] = finv[i] * i;
    }
    return finv[x];
  }
  static MInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return 0;
    if (n - k > k) k = n - k;
    return fact(n) * fact_inv(k) * fact_inv(n - k);
  }
  static MInt nPk(int n, int k) { return n < 0 || n < k || k < 0 ? 0 : fact(n) * fact_inv(n - k); }
  static MInt nHk(int n, int k) { return n < 0 || k < 0 ? 0 : (k == 0 ? 1 : nCk(n + k - 1, k)); }
  static MInt large_nCk(long long n, int k) {
    if (n < 0 || n < k || k < 0) return 0;
    inv(k, true);
    MInt res = 1;
    for (int i = 1; i <= k; ++i) res *= inv(i) * n--;
    return res;
  }
  MInt pow(long long exponent) const {
    MInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  MInt &operator+=(const MInt &x) { if((val += x.val) >= M) val -= M; return *this; }
  MInt &operator-=(const MInt &x) { if((val += M - x.val) >= M) val -= M; return *this; }
  MInt &operator*=(const MInt &x) { val = static_cast<unsigned long long>(val) * x.val % M; return *this; }
  MInt &operator/=(const MInt &x) { return *this *= inv(x.val); }
  bool operator==(const MInt &x) const { return val == x.val; }
  bool operator!=(const MInt &x) const { return val != x.val; }
  bool operator<(const MInt &x) const { return val < x.val; }
  bool operator<=(const MInt &x) const { return val <= x.val; }
  bool operator>(const MInt &x) const { return val > x.val; }
  bool operator>=(const MInt &x) const { return val >= x.val; }
  MInt &operator++() { if (++val == M) val = 0; return *this; }
  MInt operator++(int) { MInt res = *this; ++*this; return res; }
  MInt &operator--() { val = (val == 0 ? M : val) - 1; return *this; }
  MInt operator--(int) { MInt res = *this; --*this; return res; }
  MInt operator+() const { return *this; }
  MInt operator-() const { return MInt(val ? M - val : 0); }
  MInt operator+(const MInt &x) const { return MInt(*this) += x; }
  MInt operator-(const MInt &x) const { return MInt(*this) -= x; }
  MInt operator*(const MInt &x) const { return MInt(*this) *= x; }
  MInt operator/(const MInt &x) const { return MInt(*this) /= x; }
  friend std::ostream &operator<<(std::ostream &os, const MInt &x) { return os << x.val; }
  friend std::istream &operator>>(std::istream &is, MInt &x) { long long val; is >> val; x = MInt(val); return is; }
};
namespace std { template <int M> MInt<M> abs(const MInt<M> &x) { return x; } }
using ModInt = MInt<MOD>;

template <int T>
std::vector<MInt<T>> large_nCk_init(long long n, int k) {
  using ModInt = MInt<T>;
  int tmp = std::min(n, static_cast<long long>(k));
  ModInt::inv(tmp, true);
  std::vector<ModInt> c(k + 1, 0);
  c[0] = 1;
  for (int i = 1; i <= tmp; ++i) c[i] = c[i - 1] * n-- * ModInt::inv(i);
  return c;
}

int main() {
  long long m, n;
  int k;
  std::cin >> m >> n >> k;
  ModInt ans = ModInt(m).pow(n);
  std::vector<ModInt> c = large_nCk_init<MOD>(m, k - 1);
  for (int i = 1; i < k; ++i) {
    ModInt tmp = 0;
    for (int j = 1; j <= i; ++j) tmp += ModInt::nCk(i, j) * ModInt(j).pow(n) * ((i - j) & 1 ? -1 : 1);
    ans -= tmp * c[i];
  }
  std::cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3524
final_rank: 4

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 998244353;
constexpr int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
constexpr int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

template <int M>
struct MInt {
  unsigned int val;
  MInt(): val(0) {}
  MInt(long long x) : val(x >= 0 ? x % M : x % M + M) {}
  static constexpr int get_mod() { return M; }
  static void set_mod(int divisor) { assert(divisor == M); }
  static void init(int x = 10000000) { inv(x, true); fact(x); fact_inv(x); }
  static MInt inv(int x, bool init = false) {
    // assert(0 <= x && x < M && std::__gcd(x, M) == 1);
    static std::vector<MInt> inverse{0, 1};
    int prev = inverse.size();
    if (init && x >= prev) {
      // "x!" and "M" must be disjoint.
      inverse.resize(x + 1);
      for (int i = prev; i <= x; ++i) inverse[i] = -inverse[M % i] * (M / i);
    }
    if (x < inverse.size()) return inverse[x];
    unsigned int a = x, b = M; int u = 1, v = 0;
    while (b) {
      unsigned int tmp = a / b;
      std::swap(a -= tmp * b, b);
      std::swap(u -= tmp * v, v);
    }
    return u;
  }
  static MInt fact(int x) {
    static std::vector<MInt> f{1};
    int prev = f.size();
    if (x >= prev) {
      f.resize(x + 1);
      for (int i = prev; i <= x; ++i) f[i] = f[i - 1] * i;
    }
    return f[x];
  }
  static MInt fact_inv(int x) {
    static std::vector<MInt> finv{1};
    int prev = finv.size();
    if (x >= prev) {
      finv.resize(x + 1);
      finv[x] = inv(fact(x).val);
      for (int i = x; i > prev; --i) finv[i - 1] = finv[i] * i;
    }
    return finv[x];
  }
  static MInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return 0;
    if (n - k > k) k = n - k;
    return fact(n) * fact_inv(k) * fact_inv(n - k);
  }
  static MInt nPk(int n, int k) { return n < 0 || n < k || k < 0 ? 0 : fact(n) * fact_inv(n - k); }
  static MInt nHk(int n, int k) { return n < 0 || k < 0 ? 0 : (k == 0 ? 1 : nCk(n + k - 1, k)); }
  static MInt large_nCk(long long n, int k) {
    if (n < 0 || n < k || k < 0) return 0;
    inv(k, true);
    MInt res = 1;
    for (int i = 1; i <= k; ++i) res *= inv(i) * n--;
    return res;
  }
  MInt pow(long long exponent) const {
    MInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  MInt &operator+=(const MInt &x) { if((val += x.val) >= M) val -= M; return *this; }
  MInt &operator-=(const MInt &x) { if((val += M - x.val) >= M) val -= M; return *this; }
  MInt &operator*=(const MInt &x) { val = static_cast<unsigned long long>(val) * x.val % M; return *this; }
  MInt &operator/=(const MInt &x) { return *this *= inv(x.val); }
  bool operator==(const MInt &x) const { return val == x.val; }
  bool operator!=(const MInt &x) const { return val != x.val; }
  bool operator<(const MInt &x) const { return val < x.val; }
  bool operator<=(const MInt &x) const { return val <= x.val; }
  bool operator>(const MInt &x) const { return val > x.val; }
  bool operator>=(const MInt &x) const { return val >= x.val; }
  MInt &operator++() { if (++val == M) val = 0; return *this; }
  MInt operator++(int) { MInt res = *this; ++*this; return res; }
  MInt &operator--() { val = (val == 0 ? M : val) - 1; return *this; }
  MInt operator--(int) { MInt res = *this; --*this; return res; }
  MInt operator+() const { return *this; }
  MInt operator-() const { return MInt(val ? M - val : 0); }
  MInt operator+(const MInt &x) const { return MInt(*this) += x; }
  MInt operator-(const MInt &x) const { return MInt(*this) -= x; }
  MInt operator*(const MInt &x) const { return MInt(*this) *= x; }
  MInt operator/(const MInt &x) const { return MInt(*this) /= x; }
  friend std::ostream &operator<<(std::ostream &os, const MInt &x) { return os << x.val; }
  friend std::istream &operator>>(std::istream &is, MInt &x) { long long val; is >> val; x = MInt(val); return is; }
};
namespace std { template <int M> MInt<M> abs(const MInt<M> &x) { return x; } }
using ModInt = MInt<MOD>;

int main() {
  long long m, n;
  int k;
  std::cin >> m >> n >> k;
  ModInt::init(k);
  ModInt ans = ModInt(m).pow(n);
  for (int i = 1; i < k; ++i) {
    ModInt tmp = 0;
    for (int j = 1; j <= i; ++j) tmp += ModInt::nCk(i, j) * ModInt(j).pow(n) * ((i - j) & 1 ? -1 : 1);
    ans -= tmp * ModInt::large_nCk(m, i);
  }
  std::cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3472
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll mod = 998244353;
long long modpow(long long a, long long n) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

long long modinv(long long a) {
    long long b = mod, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= mod; 
    if (u < 0) u += mod;
    return u;
}

const int MAX = 510000;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i % mod;
        inv[i] = mod - inv[mod%i] * (mod / i) % mod;
        finv[i] = finv[i - 1] * inv[i] % mod;
    }
}

// 二項係数計算
long long COM(int n, int k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod;
}


signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);
    
    ll m,n,k;
    cin>>m>>n>>k;
    //n%=mod;
    m%=mod;
    ll ans = modpow(m,n);
    ll b[k]={}; // mCi中ちょうどi種類
    ll com[k]={}; com[0] = 1;
    ll in[k]={}; 
    COMinit();
    for(int i=1;i<k;i++){
        in[i] = modinv(i);
        com[i] = com[i-1] * ((m+1-i)%mod);
        com[i] %= mod;
        com[i] *= in[i];
        com[i] %= mod;
    }
    for(int i=1;i<k;i++){
        b[i] = modpow(i,n);
        for(int j=1;j<i;j++){
            b[i] += mod - (COM(i,j) * b[j])%mod;
            b[i] %= mod;
        }
    }
    ll t=0;
    for(int i=1;i<k;i++){
        t += (com[i] * b[i])%mod;
        t %= mod;
    }


    ans += mod - t;
    ans %= mod;
    cout << ans << endl;
    
}
accuracy: 1
time_ms: 40
memory_kb: 15212
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U> using Pa = pair<T, U>;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;

ll mod = 998244353;
struct mint {
    ll x;
    mint(ll x=0):x((x%mod+mod)%mod){}
    
    friend ostream &operator<<(ostream& os,const mint& a){
        return os << a.x;
    }

    friend istream &operator>>(istream& is,mint& a){
        ll t;
        is >> t;
        a = mint(t);
        return (is);
    }

    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod-a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(ll t) const {
        if (!t) return 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 res(*this);
        return res/=a;
    }
};

class combination{
public:
    vector<mint> fact,inv,finv;
    combination(int N){
        fact = inv = finv = vector<mint>(N+1);
        fact[0] = fact[1] = 1;
        inv[0] = inv[1] = 1;
        finv[0] = finv[1] = 1;
        for(ll i=2;i<=N;i++){
            fact[i] = fact[i-1]*i;
            inv[i] = (mint) mod - inv[mod%i]*(mod/i);
            finv[i] = finv[i-1]*inv[i];
        }
    }
    mint f(int i){
        return fact[i];
    }
    mint comb(int n,int k){
        if(n<k) return 0;
        if(n<0 || k<0) return 0;
        return fact[n]*finv[k]*finv[n-k];
    }
    mint hcomb(int n,int k){
        if(n==0 && k==0) return 1;
        return comb(n+k-1,k);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll M,N,K;
    cin >> M >> N >> K;
    mint ans = ((mint) M).pow(N);
    vec<mint> A(K+1);
    combination C(K);
    for(int i=1;i<min(M+1,K);i++){
        mint now = ((mint) i).pow(N);
        for(int j=1;j<i;j++) now -= A[j]*C.comb(i,j);
        A[i] = now;
        for(int j=0;j<i;j++){
            now *= (M-j)%mod;
            now /= (j+1);
        }
        ans -= now;
    }
    cout << ans << "\n";
}
accuracy: 1
time_ms: 380
memory_kb: 3252
final_rank: 12

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

int mod = MOD;
struct ModInt {
  unsigned val;
  ModInt(): val(0) {}
  ModInt(ll x) : val(x >= 0 ? x % mod : x % mod + mod) {}
  ModInt pow(ll exponent) {
    ModInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  ModInt &operator+=(const ModInt &x) { if((val += x.val) >= mod) val -= mod; return *this; }
  ModInt &operator-=(const ModInt &x) { if((val += mod - x.val) >= mod) val -= mod; return *this; }
  ModInt &operator*=(const ModInt &x) { val = static_cast<unsigned long long>(val) * x.val % mod; return *this; }
  ModInt &operator/=(const ModInt &x) { return *this *= x.inv(); }
  bool operator==(const ModInt &x) const { return val == x.val; }
  bool operator!=(const ModInt &x) const { return val != x.val; }
  bool operator<(const ModInt &x) const { return val < x.val; }
  bool operator<=(const ModInt &x) const { return val <= x.val; }
  bool operator>(const ModInt &x) const { return val > x.val; }
  bool operator>=(const ModInt &x) const { return val >= x.val; }
  ModInt &operator++() { if (++val == mod) val = 0; return *this; }
  ModInt operator++(int) { ModInt res = *this; ++*this; return res; }
  ModInt &operator--() { val = (val == 0 ? mod : val) - 1; return *this; }
  ModInt operator--(int) { ModInt res = *this; --*this; return res; }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { return ModInt(val ? mod - val : 0); }
  ModInt operator+(const ModInt &x) const { return ModInt(*this) += x; }
  ModInt operator-(const ModInt &x) const { return ModInt(*this) -= x; }
  ModInt operator*(const ModInt &x) const { return ModInt(*this) *= x; }
  ModInt operator/(const ModInt &x) const { return ModInt(*this) /= x; }
  friend ostream &operator<<(ostream &os, const ModInt &x) { return os << x.val; }
  friend istream &operator>>(istream &is, ModInt &x) { ll val; is >> val; x = ModInt(val); return is; }
private:
  ModInt inv() const {
    // assert(__gcd(val, mod) == 1);
    unsigned a = val, b = mod; int x = 1, y = 0;
    while (b) {
      unsigned tmp = a / b;
      swap(a -= tmp * b, b);
      swap(x -= tmp * y, y);
    }
    return ModInt(x);
  }
};
ModInt abs(const ModInt &x) { return x; }
struct Combinatorics {
  int val; // "val!" and "mod" must be disjoint.
  vector<ModInt> fact, fact_inv, inv;
  Combinatorics(int val = 10000000) : val(val), fact(val + 1), fact_inv(val + 1), inv(val + 1) {
    fact[0] = 1;
    FOR(i, 1, val + 1) fact[i] = fact[i - 1] * i;
    fact_inv[val] = ModInt(1) / fact[val];
    for (int i = val; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i;
    FOR(i, 1, val + 1) inv[i] = fact[i - 1] * fact_inv[i];
  }
  ModInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val && k <= val);
    return fact[n] * fact_inv[k] * fact_inv[n - k];
  }
  ModInt nPk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val);
    return fact[n] * fact_inv[n - k];
  }
  ModInt nHk(int n, int k) {
    if (n < 0 || k < 0) return ModInt(0);
    return (k == 0 ? ModInt(1) : nCk(n + k - 1, k));
  }
};

vector<ModInt> binom_large_n_init(ll n, int k, Combinatorics &com) {
  int tmp = min(n, static_cast<long long>(k));
  assert(tmp <= com.val);
  vector<ModInt> c(k + 1, 0);
  c[0] = 1;
  FOR(i, 1, tmp + 1) c[i] = c[i - 1] * n-- * com.inv[i];
  return c;
}

int main() {
  mod = 998244353;
  ll m, n; int k; cin >> m >> n >> k;
  Combinatorics com(k);
  ModInt ans = ModInt(m).pow(n);
  if (k > 1) {
    vector<ModInt> c = binom_large_n_init(m, k - 1, com);
    FOR(i, 1, k) {
      ModInt tmp = 0;
      for (int j = i; j >= 1; --j) {
        if ((i - j) % 2 == 0) {
          tmp += com.nCk(i, j) * ModInt(j).pow(n);
        } else {
          tmp -= com.nCk(i, j) * ModInt(j).pow(n);
        }
      }
      ans -= tmp * c[i];
    }
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 3216
final_rank: 6

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

int mod = MOD;
struct ModInt {
  unsigned val;
  ModInt(): val(0) {}
  ModInt(ll x) : val(x >= 0 ? x % mod : x % mod + mod) {}
  ModInt pow(ll exponent) {
    ModInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  ModInt &operator+=(const ModInt &x) { if((val += x.val) >= mod) val -= mod; return *this; }
  ModInt &operator-=(const ModInt &x) { if((val += mod - x.val) >= mod) val -= mod; return *this; }
  ModInt &operator*=(const ModInt &x) { val = static_cast<unsigned long long>(val) * x.val % mod; return *this; }
  ModInt &operator/=(const ModInt &x) { return *this *= x.inv(); }
  bool operator==(const ModInt &x) const { return val == x.val; }
  bool operator!=(const ModInt &x) const { return val != x.val; }
  bool operator<(const ModInt &x) const { return val < x.val; }
  bool operator<=(const ModInt &x) const { return val <= x.val; }
  bool operator>(const ModInt &x) const { return val > x.val; }
  bool operator>=(const ModInt &x) const { return val >= x.val; }
  ModInt &operator++() { if (++val == mod) val = 0; return *this; }
  ModInt operator++(int) { ModInt res = *this; ++*this; return res; }
  ModInt &operator--() { val = (val == 0 ? mod : val) - 1; return *this; }
  ModInt operator--(int) { ModInt res = *this; --*this; return res; }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { return ModInt(val ? mod - val : 0); }
  ModInt operator+(const ModInt &x) const { return ModInt(*this) += x; }
  ModInt operator-(const ModInt &x) const { return ModInt(*this) -= x; }
  ModInt operator*(const ModInt &x) const { return ModInt(*this) *= x; }
  ModInt operator/(const ModInt &x) const { return ModInt(*this) /= x; }
  friend ostream &operator<<(ostream &os, const ModInt &x) { return os << x.val; }
  friend istream &operator>>(istream &is, ModInt &x) { ll val; is >> val; x = ModInt(val); return is; }
private:
  ModInt inv() const {
    // assert(__gcd(val, mod) == 1);
    unsigned a = val, b = mod; int x = 1, y = 0;
    while (b) {
      unsigned tmp = a / b;
      swap(a -= tmp * b, b);
      swap(x -= tmp * y, y);
    }
    return ModInt(x);
  }
};
ModInt abs(const ModInt &x) { return x; }
struct Combinatorics {
  int val; // "val!" and "mod" must be disjoint.
  vector<ModInt> fact, fact_inv, inv;
  Combinatorics(int val = 10000000) : val(val), fact(val + 1), fact_inv(val + 1), inv(val + 1) {
    fact[0] = 1;
    FOR(i, 1, val + 1) fact[i] = fact[i - 1] * i;
    fact_inv[val] = ModInt(1) / fact[val];
    for (int i = val; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i;
    FOR(i, 1, val + 1) inv[i] = fact[i - 1] * fact_inv[i];
  }
  ModInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val && k <= val);
    return fact[n] * fact_inv[k] * fact_inv[n - k];
  }
  ModInt nPk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val);
    return fact[n] * fact_inv[n - k];
  }
  ModInt nHk(int n, int k) {
    if (n < 0 || k < 0) return ModInt(0);
    return (k == 0 ? ModInt(1) : nCk(n + k - 1, k));
  }
};

ModInt binom_large_n(ll n, int k, Combinatorics &com) {
  if (n < 0 || n < k || k < 0) return 0;
  assert(k <= com.val);
  ModInt res = 1;
  FOR(i, 1, k + 1) res *= com.inv[i] * n--;
  return res;
}

int main() {
  mod = 998244353;
  ll m, n; int k; cin >> m >> n >> k;
  Combinatorics com(k);
  ModInt ans = ModInt(m).pow(n);
  if (k > 1) {
    FOR(i, 1, k) {
      ModInt tmp = 0;
      for (int j = i; j >= 1; --j) {
        if ((i - j) % 2 == 0) {
          tmp += com.nCk(i, j) * ModInt(j).pow(n);
        } else {
          tmp -= com.nCk(i, j) * ModInt(j).pow(n);
        }
      }
      ans -= tmp * binom_large_n(m, i, com);
    }
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 3232
final_rank: 9

code_snippet: #include <algorithm>
// #include <cassert>
#include <iostream>
#include <iomanip>
#include <utility>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)

const int MOD = 998244353;

struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    cerr << fixed << setprecision(10);
  }
} iosetup;
/*-------------------------------------------------*/
int mod = MOD;
struct ModInt {
  unsigned val;
  ModInt(): val(0) {}
  ModInt(long long x) : val(x >= 0 ? x % mod : x % mod + mod) {}
  ModInt pow(long long exponent) {
    ModInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  ModInt &operator+=(const ModInt &rhs) { if((val += rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator-=(const ModInt &rhs) { if((val += mod - rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator*=(const ModInt &rhs) { val = static_cast<unsigned long long>(val) * rhs.val % mod; return *this; }
  ModInt &operator/=(const ModInt &rhs) { return *this *= rhs.inv(); }
  bool operator==(const ModInt &rhs) const { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const { return val != rhs.val; }
  bool operator<(const ModInt &rhs) const { return val < rhs.val; }
  bool operator<=(const ModInt &rhs) const { return val <= rhs.val; }
  bool operator>(const ModInt &rhs) const { return val > rhs.val; }
  bool operator>=(const ModInt &rhs) const { return val >= rhs.val; }
  ModInt operator-() const { return ModInt(val ? mod - val : 0); }
  ModInt operator+(const ModInt &rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(const ModInt &rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(const ModInt &rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(const ModInt &rhs) const { return ModInt(*this) /= rhs; }
  friend ostream &operator<<(ostream &os, const ModInt &rhs) { return os << rhs.val; }
  friend istream &operator>>(istream &is, ModInt &rhs) { long long x; is >> x; rhs = ModInt(x); return is; }
private:
  ModInt inv() const {
    // if (__gcd(val, mod) != 1) assert(false);
    unsigned a = val, b = mod; int x = 1, y = 0;
    while (b) {
      unsigned tmp = a / b;
      swap(a -= tmp * b, b);
      swap(x -= tmp * y, y);
    }
    return ModInt(x);
  }
};
int abs(const ModInt &x) { return x.val; }
struct Combinatorics {
  int val;
  vector<ModInt> fact, fact_inv, inv;
  Combinatorics(int val = 10000000) : val(val), fact(val + 1), fact_inv(val + 1), inv(val + 1) {
    fact[0] = 1;
    FOR(i, 1, val + 1) fact[i] = fact[i - 1] * i;
    fact_inv[val] = ModInt(1) / fact[val];
    for (int i = val; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i;
    FOR(i, 1, val + 1) inv[i] = fact[i - 1] * fact_inv[i];
  }
  ModInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val && k <= val);
    return fact[n] * fact_inv[k] * fact_inv[n - k];
  }
  ModInt nPk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val);
    return fact[n] * fact_inv[n - k];
  }
  ModInt nHk(int n, int k) {
    if (n < 0 || k < 0) return ModInt(0);
    return (k == 0 ? ModInt(1) : nCk(n + k - 1, k));
  }
};

vector<ModInt> nCk_init(long long n, int k, Combinatorics &com) {
  vector<ModInt> nCk(k + 1, 0);
  nCk[0] = 1;
  int tmp = min(n, static_cast<long long>(k)) + 1;
  // assert(tmp < com.val);
  FOR(i, 1, tmp) nCk[i] = nCk[i - 1] * n-- * com.inv[i];
  return nCk;
}

int main() {
  long long m, n; int k; cin >> m >> n >> k;
  Combinatorics com(k);
  ModInt ans = ModInt(m).pow(n);
  if (k > 1) {
    vector<ModInt> mCk = nCk_init(m, k - 1, com);
    FOR(i, 1, k) {
      ModInt tmp = 0;
      for (int j = i; j >= 1; --j) {
        if ((i - j) % 2 == 0) {
          tmp += com.nCk(i, j) * ModInt(j).pow(n);
        } else {
          tmp -= com.nCk(i, j) * ModInt(j).pow(n);
        }
      }
      ans -= tmp * mCk[i];
    }
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 3228
final_rank: 7

code_snippet: // #include <algorithm>
// #include <cassert>
#include <iostream>
#include <iomanip>
#include <utility>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)

const int MOD = 998244353;

struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    cerr << fixed << setprecision(10);
  }
} iosetup;
/*-------------------------------------------------*/
int mod = MOD;
struct ModInt {
  unsigned val;
  ModInt(): val(0) {}
  ModInt(long long x) : val(x >= 0 ? x % mod : x % mod + mod) {}
  ModInt pow(long long exponent) {
    ModInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  ModInt &operator+=(const ModInt &rhs) { if((val += rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator-=(const ModInt &rhs) { if((val += mod - rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator*=(const ModInt &rhs) { val = static_cast<unsigned long long>(val) * rhs.val % mod; return *this; }
  ModInt &operator/=(const ModInt &rhs) { return *this *= rhs.inv(); }
  bool operator==(const ModInt &rhs) const { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const { return val != rhs.val; }
  bool operator<(const ModInt &rhs) const { return val < rhs.val; }
  bool operator<=(const ModInt &rhs) const { return val <= rhs.val; }
  bool operator>(const ModInt &rhs) const { return val > rhs.val; }
  bool operator>=(const ModInt &rhs) const { return val >= rhs.val; }
  ModInt operator-() const { return ModInt(val ? mod - val : 0); }
  ModInt operator+(const ModInt &rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(const ModInt &rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(const ModInt &rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(const ModInt &rhs) const { return ModInt(*this) /= rhs; }
  friend ostream &operator<<(ostream &os, const ModInt &rhs) { return os << rhs.val; }
  friend istream &operator>>(istream &is, ModInt &rhs) { long long x; is >> x; rhs = ModInt(x); return is; }
private:
  ModInt inv() const {
    // if (__gcd(val, mod) != 1) assert(false);
    unsigned a = val, b = mod; int x = 1, y = 0;
    while (b) {
      unsigned tmp = a / b;
      swap(a -= tmp * b, b);
      swap(x -= tmp * y, y);
    }
    return ModInt(x);
  }
};
int abs(const ModInt &x) { return x.val; }
struct Combinatorics {
  int val;
  vector<ModInt> fact, fact_inv, inv;
  Combinatorics(int val = 10000000) : val(val), fact(val + 1), fact_inv(val + 1), inv(val + 1) {
    fact[0] = 1;
    FOR(i, 1, val + 1) fact[i] = fact[i - 1] * i;
    fact_inv[val] = ModInt(1) / fact[val];
    for (int i = val; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i;
    FOR(i, 1, val + 1) inv[i] = fact[i - 1] * fact_inv[i];
  }
  ModInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val && k <= val);
    return fact[n] * fact_inv[k] * fact_inv[n - k];
  }
  ModInt nPk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    // assert(n <= val);
    return fact[n] * fact_inv[n - k];
  }
  ModInt nHk(int n, int k) {
    if (n < 0 || k < 0) return ModInt(0);
    return (k == 0 ? ModInt(1) : nCk(n + k - 1, k));
  }
};

ModInt nCk(long long n, int k, Combinatorics &com) {
  if (n < 0 || n < k || k < 0) return 0;
  // assert(k <= com.val);
  ModInt res = 1;
  FOR(i, 1, k + 1) res *= com.inv[i] * n--;
  return res;
}

int main() {
  long long m, n; int k; cin >> m >> n >> k;
  Combinatorics com(k);
  ModInt ans = ModInt(m).pow(n);
  if (k > 1) {
    FOR(i, 1, k) {
      ModInt tmp = 0;
      for (int j = i; j >= 1; --j) {
        if ((i - j) % 2 == 0) {
          tmp += com.nCk(i, j) * ModInt(j).pow(n);
        } else {
          tmp -= com.nCk(i, j) * ModInt(j).pow(n);
        }
      }
      ans -= tmp * nCk(m, i, com);
    }
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 3220
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define N (long long)(998244353)
#define MAX 500000
using namespace std;

long long factorial[MAX] = {0}, finverse[MAX] = {0},
          inverse[MAX] = {0};

void smodfact() {
  factorial[0] = factorial[1] = 1;
  finverse[0] = finverse[1] = 1;
  inverse[1] = 1;
  for(int i = 2; i < MAX; ++i) {
    factorial[i] = factorial[i - 1] * i % N;
    inverse[i] = N - (inverse[N % i] * (N / i)) % N;
    finverse[i] = finverse[i - 1] * inverse[i] % N;
  }
}

long long calccomb(long long n, long long k) {
  if(n == k && n == 0) return 1;
  if(n < 0 || k < 0 || n < k) return 0;
  return factorial[n] * finverse[k] % N * finverse[n - k] %
         N;
}

// as + bt = GCD(a,b) a,b:const s,t:var(any)
// return GCD(a,b)
long long extGCD(long long a, long long b, long long& s,
                 long long& t) {
  s = 1, t = 0;
  while(b) {
    long long tmp = a / b;
    a -= b * tmp;
    s -= t * tmp;
    swap(a, b);
    swap(s, t);
  }
  return a;
}

// (mod)x+ay=1, calculate y -> a^-1 (mod m) (a,m : coprime)
long long calcinv(long long a, long long m) {
  long long s, t;
  extGCD(a, m, s, t);
  return (s + m) % m;
}

long long mod_pow(long long x, long long n, long long mod) {
  long long res = 1;
  while(n > 0) {
    if(n & 1) (res *= x) %= mod;
    (x *= x) %= mod;
    n >>= 1;
  }
  return res;
}

long long m, n, k;
long long mci[1005] = {0};
long long dp[1005][1005] = {0};

long long solve();

int main() {
  cin >> m >> n >> k;
  cout << solve() << endl;
  return 0;
}

long long solve() {
  if(m < k) return 0;
  smodfact();
  long long ans = mod_pow(m % N, n, N);
  mci[0] = 1LL;
  for(long long i = 0; i < k; ++i)
    mci[i + 1] =
        mci[i] * ((m - i) % N) % N * calcinv(i + 1, N) % N;
  // dp
  dp[0][0] = 1;
  for(long long i = 1; i <= k; ++i)
    for(long long j = 1; j <= i; ++j) {
      if(i != j) {
        dp[i][j] = calccomb(i, j) * dp[j][j] % N;
        (dp[i][j] += dp[i][j - 1]) %= N;
      }
      else {
        dp[i][j] = mod_pow(i % N, n, N);
        dp[i][j] -= dp[i][j - 1];
        (dp[i][j] += N) %= N;
      }
    }

  for(int i = 0; i < k - 1; ++i) {
    ans -= mci[i + 1] * dp[i + 1][i + 1] % N;
    (ans += N) %= N;
  }
  return ans;
}
accuracy: 1
time_ms: 10
memory_kb: 21676
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int64_t MOD = 998244353;
void add(int64_t& a, int64_t b){
    a %= MOD;
    b %= MOD;
    a = (a+b) % MOD;
}
void mul(int64_t& a, int64_t b){
    a %= MOD;
    b %= MOD;
    a = a*b % MOD;
}

vector<int64_t> fact, seq_inv, fact_inv;

void create_fact_mod(int num){
    fact[0] = fact[1] = 1;
    for(int i=2; i<=num; i++) fact[i] = fact[i-1] * i % MOD;
}

void create_seq_inv_mod(int num){
    seq_inv[0] = seq_inv[1] = 1;
    for(int i=2; i<=num; i++) seq_inv[i] = (MOD - MOD/i) * seq_inv[MOD%i] % MOD;
}

void create_fact_inv_mod(int num){
    fact_inv[0] = fact_inv[1] = 1;
    for(int i=2; i<=num; i++) fact_inv[i] = fact_inv[i-1] * seq_inv[i] % MOD;
}

void create_mod_tables(int num){
    fact.resize(num+1);
    seq_inv.resize(num+1);
    fact_inv.resize(num+1);
    create_fact_mod(num);
    create_seq_inv_mod(num);
    create_fact_inv_mod(num);
}

int64_t comb_mod(int n, int k){
    return fact[n] * fact_inv[n-k] % MOD * fact_inv[k] % MOD;
}

int64_t perm_mod(int n, int k){
    return fact[n] * fact_inv[n-k] % MOD;
}

int64_t power_mod(int64_t num, int64_t power){
    int64_t prod = 1;
    num %= MOD;
    power %= (MOD-1);
    while(power > 0){
        if(power&1) prod = prod * num % MOD;
        num = num * num % MOD;
        power >>= 1;
    }
    return prod;
}

int main() {
    int64_t M, N, K;
    cin >> M >> N >> K;
    if(M < K){
        cout << 0 << endl;
        return 0;
    }
    create_mod_tables(1000);
    int64_t ans = power_mod(M, N);
    for(int k=1; k<K; k++){
        int64_t res = 0;
        for(int m=1; m<=k; m++) add(res, MOD + ((k-m)%2 ? -1 : 1) * comb_mod(k, m) * power_mod(m, N) % MOD);
        for(int i=0; i<k; i++) mul(res, M-i);
        mul(res, fact_inv[k]);
        add(ans, MOD - res);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3148
final_rank: 2

code_snippet: #include<iostream>
using namespace std;
typedef long long ll;

const ll mod = 998244353;

ll modpow(ll a, ll b, ll p = mod){
    if(b == 0)  return 1;

    if(b % 2 == 0){
        ll d = modpow(a, b/2, p);
        return (d*d) % p;
    }else{
        return (a%p * modpow(a, b-1, p)) % p;
    }
}

int main(){
    ll m, n, k;
    cin >> m >> n >> k;
    ll ans = modpow(m, n);
    ll sub = 0, mcomb = 1;
    for(int i = 1; i < min(k, m+1); i++){
        ll tmp = 0, comb = 1;
        for(int j = 1; j <= i; j++){
            ll x = (i-j)%2 == 0 ? 1 : -1;
            comb = comb*modpow(j,mod-2)%mod*(i-j+1)%mod;
            tmp += x*(comb*modpow(j,n)%mod);
            tmp = (tmp + mod)%mod;
        }
        mcomb = mcomb*modpow(i,mod-2)%mod*((m-i+1)%mod)%mod;
        tmp = tmp*mcomb%mod;
        sub += tmp;
        sub %= mod;
    }
    cout << (ans-sub+mod)%mod << endl;
    return 0;
}
accuracy: 1
time_ms: 1110
memory_kb: 3104
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;

constexpr ll MOD = 998244353;

ll power(ll x, ll n){
    x %= MOD;
    ll res = 1;
    while(n > 0){
        if(n&1){
            res *= x;
            res %= MOD;
        }
        x *= x;
        x %= MOD;
        n >>= 1;
    }
    return res;
}

ll mod_inv(ll x){
    return power(x, MOD-2);
}

vector<ll> factrial, inverse;

void init(ll n) {
    factrial.resize(n+1);
    inverse.resize(n+1);
    factrial[0] = 1;
    inverse[0] = 1;
    for (ll i = 1; i <= n; i++) {
        factrial[i] = (factrial[i - 1] * i) % MOD;
        inverse[i] = mod_inv(factrial[i]);
    }
}

ll nCk(ll n, ll k) {
    if(n < 0 || k < 0 || n < k) return 0;
    return factrial[n] * inverse[k] % MOD * inverse[n - k] % MOD;
}

ll nCk_big(ll n, ll k){
    if(k == 0) return 1;
    else return nCk_big(n, k-1) * ((n-k+1)%MOD) % MOD * mod_inv(k) % MOD;
}

// x種類の文字ですべての文字が少なくとも1回現れる長さnの文字列の数
ll calc(ll x, ll n){
    ll res = 0;
    for(int i=0;i<x;i++){
        res += power(x-i,n)*nCk(x,x-i)%MOD*(i%2?-1:1);
        res = (res%MOD+MOD)%MOD;
    }
    return res;
}

int main(){
    ll m, n, k, ans;
    cin >> m >> n >> k;
    init(k);
    ans = power(m,n);
    for(int i=1;i<k;i++){
        ans -= calc(i,n)*nCk_big(m,i)%MOD;
        ans = (ans%MOD+MOD)%MOD;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3152
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
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;
}
typedef long long int ll;

#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define endl "\n"
const double EPS = 1e-7;
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
const double PI = acos(-1);
const int MOD = 998244353;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

const int MAX = 500000;

ll fac[MAX], finv[MAX], inv[MAX];

void COMinit() // 二項係数を求める時は前処理としてCOMinit()をする
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++)
    {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算
long long COM(int n, int k)
{
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll pow_mod(ll n, ll k, ll mod)
{
    if (k == 0)
    {
        return 1;
    }
    else if (k % 2 == 1)
    {
        return pow_mod(n, k - 1, mod) * n % mod;
    }
    else
    {
        ll t = pow_mod(n, k / 2, mod);
        return t * t % mod;
    }
}

ll modinv(ll a, ll m)
{
    ll b = m, u = 1, v = 0;
    while (b)
    {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= m;
    if (u < 0)
        u += m;
    return u;
}

ll kaijyo(ll n)
{
    if (n == 0)
    {
        return 1;
    }
    return n * kaijyo(n - 1) % MOD;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll m, n, k;
    cin >> m >> n >> k;
    m %= MOD;
    // n %= MOD;
    ll ans = pow_mod(m, n, MOD);
    ll b[k] = {};
    ll com[k] = {};
    com[0] = 1;
    ll in[k] = {};
    COMinit();
    for (ll i = 1; i < k; i++)
    {
        in[i] = modinv(i, MOD);
        com[i] = com[i - 1] * ((m + 1 - i) % MOD) % MOD;
        (com[i] *= in[i]) %= MOD;
    }
    for (ll i = 1; i < k; i++)
    {
        b[i] = pow_mod(i, n, MOD);
        for (ll j = 1; j < i; j++)
        {
            (b[i] += MOD - (COM(i, j) * b[j]) % MOD) %= MOD;
        }
    }
    ll t = 0;
    for (ll i = 1; i < k; i++)
    {
        (t += (com[i] * b[i]) % MOD) %= MOD;
    }

    (ans += MOD - t) %= MOD;
    cout << ans << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 14952
final_rank: 13

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 998244353 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

vector<ll> factmemo, factmemoInv;
ll factmemoMod = -1;

ll factorial(int n, int M){
  if(factmemoMod == M) return factmemo[n];
  if(n <= 1) return 1;

  ll res = 1;
  for(int i=1; i<=n; i++) res = res * i % M;
  return res;
}

ll power(ll k, ll n, int M){
  k %= M;
  if(n == 0) return 1;
  if(n == 1) return (ll)k;

  ll res = power(k, n/2, M);

  res = res * res % M;
  return n%2 == 1 ? res * k % M : res;
}

void initFactorial(int n, int M){
  factmemo.assign(n+1, 0);
  factmemoInv.assign(n+1, 0);
  factmemoMod = M;
  factmemo[0] = 1;
  for(int i=1;i<=n;i++) factmemo[i] = factmemo[i-1] * i % M;
  factmemoInv[n] = power(factmemo[n], M-2, M);
  for(int i=n;i>0;i--) factmemoInv[i-1] = factmemoInv[i] * i % M;
}

//nCm nPm nHm (mod M)

/*Combination*/
ll C(int n, int m, int M){
  if(n < m) return 0;
  if(m == 0 || n == m) return 1;

  if(factmemoMod == M)
    return factmemo[n] * factmemoInv[m] % M * factmemoInv[n-m] % M;

  ll numer = factorial(n, M);
  ll denom = factorial(m, M) * factorial(n-m, M) % M;

  denom = power((int)denom, M-2, M);

  return numer * denom % M;
}
/*Permutation*/
ll P(int n, int m, int M){
  if(n < m) return 0;
  if(m == 0) return 1;

  if(factmemoMod == M)
    return factmemo[n] * factmemoInv[n-m] % M;

  ll numer = factorial(n, M);
  ll denom = factorial(n-m, M);

  denom = power((int)denom, M-2, M);

  return numer * denom % M;
}
/*Combination with Repetitions*/
ll H(int n, int m, int M){
  if(n == 0 && m == 0) return 1;
  return C(n+m-1, m, M);
}

ll Mfactk[1010], factk[1010], factkInv[1010];

int main(){
  ll M, N, K;

  cin >> M >> N >> K;

  ll ans = 0;

  if (K > M) {
    puts("0");
    return 0;
  }

  Mfactk[0] = M % mod;
  factk[0] = 1;
  for(int i=1; i<=K; i++) {
    factk[i]  = factk[i-1] * i % mod;
    Mfactk[i] = Mfactk[i-1] * ((M - i) % mod) % mod;
  }

  for(int i=0; i<=K; i++) {
    factkInv[i] = power(factk[i], mod-2, mod);
  }

  ll v[1010];

  for(int i=1; i<K; i++) {
    v[i] = 0;

    ll fact = i;

    for(int j=1; j<=i; j++) {
      ll add = power(j, N, mod) * fact % mod * factkInv[j] % mod;
      fact = fact * (i - j) % mod;
      v[i] = (v[i] + mod + add * ((i - j) % 2 ? -1 : 1)) % mod;
    }
  }

  for(int i=1; i<K; i++) {
    ll add = Mfactk[i-1] * factkInv[i] % mod * v[i];
    ans = (ans + add) % mod;
  }

  ans = (power(M, N, mod) + mod - ans) % mod;

  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 3152
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define LLINF 1000000000000000ll
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define all(x) (x).begin(),(x).end()
#define sq(x) ((x)*(x))
#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)
#define EQ(a,b) (abs((a)-(b))<eps)
#define dmp(x) cerr << __LINE__ << " " << #x << " " << x << endl;
template<class T> void chmin(T& a,const T& b){if(a>b)a=b;}
template<class T> void chmax(T& a,const T& b){if(a<b)a=b;}
template<class T,class U>
ostream& operator << (ostream& os,pair<T,U>& p){
	os << p.fi << ',' << p.sec; return os;
}
template<class T,class U>
istream& operator >> (istream& is,pair<T,U>& p){
	is >> p.fi >> p.sec; return is;
}
template<class T>
ostream& operator << (ostream &os,const vector<T> &vec){
	for(int i=0;i<vec.size();i++){
		os << vec[i];
		if(i+1<vec.size())os << ' ';
	}
	return os;
}
template<class T>
istream& operator >> (istream &is,vector<T>& vec){
	for(int i=0;i<vec.size();i++)is >> vec[i];
	return is;
}
void fastio(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
}
// How to devide :
// ModInt a(6ll);
// ModInt b(2ll);
// a *= b.exp(MOD-2ll);  -> a/=b;  result: a = 3
ll MOD = 998244353ll; // if inv is needed, this shold be prime.
struct ModInt{
	ll val;
	ModInt():val(0ll){}
	ModInt(ll v):val(((v%MOD)+MOD)%MOD){}
	ModInt exp(ll y)const{
		if(!y)return ModInt(1ll);
		ModInt a = exp(y/2ll);
		a *= a;
		if(y&1)a*=(*this);
		return a;
	}
	bool operator==(const ModInt& x)const{return val==x.val;}
	inline bool operator!=(const ModInt& x)const{return !(*this==x);}
	bool operator<(const ModInt& x)const{return val<x.val;}
	bool operator>(const ModInt& x)const{return val>x.val;}
	inline bool operator>=(const ModInt& x)const{return !(*this<x);}
	inline bool operator<=(const ModInt& x)const{return !(*this>x);}
	ModInt& operator+=(const ModInt& x){if((val+=x.val)>=MOD)val-=MOD;return *this;}
	ModInt& operator-=(const ModInt& x){if((val+=MOD-x.val)>=MOD)val-=MOD;return *this;}
	ModInt& operator*=(const ModInt& x){(val*=x.val)%=MOD;return *this;}
	ModInt operator+(const ModInt& x)const{return ModInt(*this)+=x;}
	ModInt operator-(const ModInt& x)const{return ModInt(*this)-=x;}
	ModInt operator*(const ModInt& x)const{return ModInt(*this)*=x;}
};
istream& operator>>(istream&i,ModInt&x){i>>x.val;return i;}
ostream& operator<<(ostream&o,const ModInt&x){o<<x.val;return o;}
ModInt pow(ModInt a,ll x){
	ModInt res = ModInt(1ll);
	while(x){
		if(x&1ll)res *= a;
		x >>= 1;
		a = a*a;
	}
	return res;
}
const int SIZE = 100100;
ModInt inv[SIZE+10],fac[SIZE+10],facinv[SIZE+10];
// notice: 0C0 = 1 
ModInt nCr(int n,int r){
	assert(!(n<r));
	assert(!(n<0||r<0));
	return fac[n]*facinv[r]*facinv[n-r];
}
void init(){
	fac[0]=ModInt(1ll);
	for(int i=1;i<=SIZE;i++)fac[i]=fac[i-1]*ModInt(i);
	inv[1]=ModInt(1ll);
	for(int i=2;i<=SIZE;i++)inv[i]=ModInt(0ll)-ModInt(MOD/i)*inv[MOD%i];
	facinv[0]=ModInt(1ll);
	for(int i=1;i<=SIZE;i++)facinv[i]=facinv[i-1]*inv[i];
	return;
}
ModInt nCk(ll n,ll k){
  ModInt ret = ModInt(1ll);
  for(int i=0;i<k;i++){
    ret *= ModInt(n-i);
  }
  for(int i=1;i<=k;i++){
    ret *= pow(ModInt(i),MOD-2);
  }
  return ret;
}
ll M,N,K;
ModInt y[100100];
ModInt a[100100];
ModInt b[100100];
int main(){
  cin >> M >> N >> K;
  ModInt ans = pow(ModInt(M),N);
  a[0] = ModInt(M);
  for(int i=1;i<=3*K;i++){
    a[i] = a[i-1]*ModInt(M-i);
  }
  b[0] = ModInt(1ll);
  for(int i=1;i<=3*K;i++){
    b[i] = b[i-1]*ModInt(i);
  }
  for(int i=1;i<K;i++){
    if(i>M)break;
    y[i] = nCk(M,i)*pow(ModInt(i),N);
    for(int j=1;j<i;j++){
      y[i]-=y[j]*a[i-1]*pow(a[j-1],MOD-2ll)*pow(b[i-j],MOD-2ll);
    }
    // cout << y[i] << endl;
    ans -= y[i];
  }
  cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 7816
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define spa << " " <<
#define lfs <<fixed<<setprecision(10)<<
#define test cout<<"test"<<endl;
#define fi first
#define se second
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = n; i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = n - 1; i >= (ll)(m); i--)
typedef long long ll;
typedef long double ld;
//const ll MOD = 1e9+7;
const ll MOD = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T>
void chmin(T &a,T b){if(a>b)a=b;}
template<typename T>
void chmax(T &a,T b){if(a<b)a=b;}
void pmod(ll &a,ll b){a=(a+b)%MOD;}
void pmod(ll &a,ll b,ll c){a=(b+c)%MOD;}
void qmod(ll &a,ll b){a=(a*b)%MOD;}
void qmod(ll &a,ll b,ll c){a=(b*c)%MOD;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>
void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T>
void debug(vector<vector<T>>v,ll h,ll w){for(ll i=0;i<h;i++)
{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};
void debug(vector<string>v,ll h,ll w){for(ll i=0;i<h;i++)
{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};
template<typename T>
void debug(vector<T>v,ll n){cout<<v[0];
for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};
template<typename T>
vector<vector<T>>vec(ll x, ll y, T w){
  vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
template<typename T>
void emp(map<T,ll>&m, T x){m.emplace(x,0).first->second++;}
vector<ll>dx={1,0,-1,0,1,1,-1,-1};
vector<ll>dy={0,1,0,-1,1,-1,1,-1};
template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}

template< int mod >
struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t 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; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }

  static int get_mod() { return mod; }
};
using modint = ModInt< MOD >;

template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;

  Combination(ll sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(ll i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(ll i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(ll i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }

  inline T fact(ll k) const { return _fact[k]; }

  inline T rfact(ll k) const { return _rfact[k]; }

  inline T inv(ll k) const { return _inv[k]; }

  T P(ll n, ll r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }

  T C(ll p, ll q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }

  T H(ll n, ll r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
using Comb=Combination<modint>;


int main(){
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);
  ll res=0,res1=INF,res2=-INF,buf=0;
  bool judge = true;
  ll m,n,k;cin>>m>>n>>k;
  vector<modint>dp(k);//i種類ちょうどのときの余事象
  vector<modint>p(k);
  vector<modint>b(k);//dpの累積和
  Comb comb(10000);
  rep(i,1,min(m+1,k)){
    modint tmp=i;
    tmp=tmp.pow(n);
    modint com=1;//mCiを計算
    rrep(j,m+1,max(0LL,m-i+1)){
      com*=modint(j);
    }
    rep(j,1,i+1)com/=modint(j);
    if(com==0)com=1;
    p[i]=tmp;
    dp[i]=tmp*com;
    rep(j,1,i){
      p[i]-=p[j]*comb.C(i,j);
      dp[i]-=p[j]*comb.C(i,j)*com;
    }
    b[i]=dp[i]+b[i-1];
  }
  modint ret=m;
  ret=ret.pow(n);
  ret-=b[min(m+1,k)-1];
  //debug(p,k);
  //debug(dp,k);
  //debug(b,k);
  cout<<ret<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3344
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
const ll MOD=998244353;

#define MAX_N 200020
ll inv[MAX_N+10],fac[MAX_N+10],ifac[MAX_N+10];

void setComb(){
  inv[0]=1;inv[1]=1;fac[1]=1;ifac[1]=1;fac[0]=1;ifac[0]=1;
  for(int i=2;i<MAX_N;i++){
    inv[i]=(-MOD/i)*inv[MOD%i]%MOD;
    fac[i]=fac[i-1]*i%MOD;
    ifac[i]=ifac[i-1]*inv[i]%MOD;

    inv[i]=(inv[i]+MOD)%MOD;
    fac[i]=(fac[i]+MOD)%MOD;
    ifac[i]=(ifac[i]+MOD)%MOD;
  }
  return;
}

ll comb(ll n,ll k){
  if(n<k||n<0||k<0) return 0;
  else return ((fac[n]*ifac[k]%MOD*ifac[n-k]%MOD+MOD)%MOD);
}

ll hcomb(ll n,ll r){
  if(n==0&&r==0) return 1;
  else if(n<0||r<0) return 0;
  else return comb(n+r-1,r-1);
}

ll mod_pow(ll x,ll n){
    x%=MOD;
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%MOD;
        x=x*x%MOD;
        n/=2;
    }
    return res;
}

void add(ll &a,ll b){
    a=(a+b)%MOD;
}

void mul(ll &a,ll b){
    a=a*b%MOD;
}


ll N,M,K;

int main(){
  cin>>M>>N>>K;

  setComb();

  ll nans=0;
  for(ll i=1;i<=min(M,K-1);i++){
      ll c=ifac[i];
      for(ll j=0;j<i;j++){
          mul(c,(M-j)%MOD);
      }

      ll res=0;
      for(ll j=1;j<=i;j++){
          ll p=mod_pow(j,N);
          mul(p,comb(i,j));
          if((i-j)%2==0) add(res,p);
          else add(res,MOD-p);
      }
      mul(res,c);
      add(nans,res);
  }

  ll ans=mod_pow(M,N);
  add(ans,MOD-nans);
  cout<<ans<<endl;

  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 7812
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

template<ll MOD>
struct modint {
    ll x;
    modint(): x(0) {}
    modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
    static constexpr ll mod() { return MOD; }
    // e乗
    modint pow(ll e) {
        ll a = 1, p = x;
        while(e > 0) {
            if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
            else {a = (a*p) % MOD; e--;}
        }
        return modint(a);
    }
    modint inv() const {
        ll a=x, b=MOD, u=1, y=1, v=0, z=0;
        while(a) {
            ll q = b/a;
            swap(z -= q*u, u);
            swap(y -= q*v, v);
            swap(b -= q*a, a);
        }
        return z;
    }
    // Comparators
    bool operator <(modint b) { return x < b.x; }
    bool operator >(modint b) { return x > b.x; }
    bool operator<=(modint b) { return x <= b.x; }
    bool operator>=(modint b) { return x >= b.x; }
    bool operator!=(modint b) { return x != b.x; }
    bool operator==(modint b) { return x == b.x; }
    // Basic Operations
    modint operator+(modint r) const { return modint(*this) += r; }
    modint operator-(modint r) const { return modint(*this) -= r; }
    modint operator*(modint r) const { return modint(*this) *= r; }
    modint operator/(modint r) const { return modint(*this) /= r; }
    modint &operator+=(modint r) {
        if((x += r.x) >= MOD) x -= MOD;
        return *this;
    }
    modint &operator-=(modint r) {
        if((x -= r.x) < 0) x += MOD;
        return *this;
    }
    modint &operator*=(modint r) {
    #if !defined(_WIN32) || defined(_WIN64)
        x = x * r.x % MOD; return *this;
    #endif
        unsigned long long y = x * r.x;
        unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
        asm(
            "divl %4; nt"
            : "=a" (d), "=d" (m)
            : "d" (xh), "a" (xl), "r" (MOD)
        );
        x = m;
        return *this;
    }
    modint &operator/=(modint r) { return *this *= r.inv(); }
    // increment, decrement
    modint operator++() { x++; return *this; }
    modint operator++(signed) { modint t = *this; x++; return t; }
    modint operator--() { x--; return *this; }
    modint operator--(signed) { modint t = *this; x--; return t; }

    template<class T>
    friend modint operator*(T l, modint r) { return modint(l) *= r; }
    template<class T>
    friend modint operator+(T l, modint r) { return modint(l) += r; }
    template<class T>
    friend modint operator-(T l, modint r) { return modint(l) -= r; }
    template<class T>
    friend modint operator/(T l, modint r) { return modint(l) /= r; }
    template<class T>
    friend bool operator==(T l, modint r) { return modint(l) == r; }
    template<class T>
    friend bool operator!=(T l, modint r) { return modint(l) != r; }
    // Input/Output
    friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
    friend istream &operator>>(istream& is, modint &a) { return is >> a.x; }
    friend string to_frac(modint v) {
        static map<ll, PII> mp;
        if(mp.empty()) {
            mp[0] = mp[MOD] = {0, 1};
            FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
                mp[(modint(i) / j).x] = {i, j};
            }
        }
        auto itr = mp.lower_bound(v.x);
        if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
        string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
        if(itr->second.second > 1) {
            ret += '/';
            ret += to_string(itr->second.second);
        }
        return ret;
    }
};
using mint = modint<998244353>;

// 前計算O(N) クエリO(1)
mint combi(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint fact[maxN+1]={},factr[maxN+1]={};
    if (fact[0]==0) {
        fact[0] = factr[0] = 1;
        FOR(i, 1, maxN+1) fact[i] = fact[i-1] * i;
        factr[maxN] = fact[maxN].inv();
        for(ll i=maxN-1; i>=0; --i) factr[i] = factr[i+1] * (i+1);
    }
    if(K<0 || K>N) return 0; // !!!
    return factr[K]*fact[N]*factr[N-K];
}

// 前計算O(Klog(mod)) クエリO(K)
mint combi_bigN(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint inv[maxN+1] = {};
    if(inv[0]==0) {
        inv[0] = 1;
        FOR(i, 1, maxN+1) inv[i] = mint(i).inv();
    }
    if(K<0 || K>N) return 0; // !!!
    mint ret = 1;
    for(;K>0;N--,K--) ret *= N, ret *= inv[K];
    return ret;
}

signed main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);

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

    mint ans = mint(m).pow(n);
    FOR(i, 1, k) {
        mint tmp = 0;
        FOR(j, 1, i+1) {
            if((i-j)%2 == 0) {
                tmp += combi(i, j) * mint(j).pow(n);
            } else {
                tmp -= combi(i, j) * mint(j).pow(n);
            }
        }
        ans -= tmp * combi_bigN(m, i);
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 14932
final_rank: 16

code_snippet: #include <algorithm>
// #include <cassert>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)

const int MOD = 998244353;
/*-------------------------------------------------*/
int mod = MOD;
struct ModInt {
  unsigned val;
  ModInt(): val(0) {}
  ModInt(long long x) : val(x >= 0 ? x % mod : x % mod + mod) {}
  ModInt pow(long long exponent) {
    ModInt tmp = *this, res = 1;
    while (exponent > 0) {
      if (exponent & 1) res *= tmp;
      tmp *= tmp;
      exponent >>= 1;
    }
    return res;
  }
  ModInt &operator+=(const ModInt &rhs) { if((val += rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator-=(const ModInt &rhs) { if((val += mod - rhs.val) >= mod) val -= mod; return *this; }
  ModInt &operator*=(const ModInt &rhs) { val = (unsigned long long)val * rhs.val % mod; return *this; }
  ModInt &operator/=(const ModInt &rhs) { return *this *= rhs.inv(); }
  bool operator==(const ModInt &rhs) const { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const { return val != rhs.val; }
  bool operator<(const ModInt &rhs) const { return val < rhs.val; }
  bool operator<=(const ModInt &rhs) const { return val <= rhs.val; }
  bool operator>(const ModInt &rhs) const { return val > rhs.val; }
  bool operator>=(const ModInt &rhs) const { return val >= rhs.val; }
  ModInt operator-() const { return ModInt(-val); }
  ModInt operator+(const ModInt &rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(const ModInt &rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(const ModInt &rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(const ModInt &rhs) const { return ModInt(*this) /= rhs; }
  friend ostream &operator<<(ostream &os, const ModInt &rhs) { return os << rhs.val; }
  friend istream &operator>>(istream &is, ModInt &rhs) { long long x; is >> x; rhs = ModInt(x); return is; }
private:
  ModInt inv() const {
    // if (__gcd((int)val, mod) != 1) assert(false);
    unsigned a = val, b = mod; int x = 1, y = 0;
    while (b) {
      unsigned tmp = a / b;
      swap(a -= tmp * b, b);
      swap(x -= tmp * y, y);
    }
    return ModInt(x);
  }
};
ModInt abs(const ModInt &x) { return x.val; }
struct Combinatorics {
  Combinatorics(int MAX = 5000000) {
    MAX <<= 1;
    fact.resize(MAX + 1);
    fact_inv.resize(MAX + 1);
    fact[0] = 1;
    FOR(i, 1, MAX + 1) fact[i] = fact[i - 1] * i;
    fact_inv[MAX] = ModInt(1) / fact[MAX];
    for (int i = MAX; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i;
  }
  ModInt nCk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    return fact[n] * fact_inv[k] * fact_inv[n - k];
  }
  ModInt nPk(int n, int k) {
    if (n < 0 || n < k || k < 0) return ModInt(0);
    return fact[n] * fact_inv[n - k];
  }
  ModInt nHk(int n, int k) {
    if (n < 0 || k < 0) return ModInt(0);
    return (k == 0 ? ModInt(1) : nCk(n + k - 1, k));
  }
private:
  vector<ModInt> fact, fact_inv;
};

vector<long long> inv_init(int val, long long mod = MOD) {
  vector<long long> inv(val + 1, 0);
  if (val >= 1) {
    inv[1] = 1;
    FOR(i, 2, val + 1) {
      inv[i] = mod - inv[mod % i] * (mod / i) % mod;
      if (inv[i] == mod) inv[i] = 0;
    }
  }
  return inv;
}

long long nCk(long long n, int k, long long mod = MOD) {
  if (n < 0 || n < k || k < 0) return 0;
  vector<long long> k_inv = inv_init(k, mod);
  long long res = 1;
  FOR(i, 1, k + 1) (res *= (n-- % mod) * k_inv[i] % mod) %= mod;
  return res;
}

int main() {
  cin.tie(nullptr); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  long long m, n; int k; cin >> m >> n >> k;
  Combinatorics com(k);
  ModInt ans = ModInt(m).pow(n);
  if (k > 1) {
    FOR(i, 1, k) {
      ModInt tmp = 0;
      for (int j = i; j >= 1; --j) {
        if ((i - j) % 2 == 0) {
          tmp += com.nCk(i, j) * ModInt(j).pow(n);
        } else {
          tmp -= com.nCk(i, j) * ModInt(j).pow(n);
        }
      }
      ans -= tmp * nCk(m, i);
    }
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 3240
final_rank: 10