Problem:
Score : 500 points

Problem Statement

There are N blocks arranged in a row. Let us paint these blocks.

We will consider two ways to paint the blocks different if and only if there is a block painted in different colors in those two ways.

Find the number of ways to paint the blocks under the following conditions:

For each block, use one of the M colors, Color 1 through Color M, to paint it. It is not mandatory to use all the colors.

There may be at most K pairs of adjacent blocks that are painted in the same color.

Since the count may be enormous, print it modulo 998244353.

Constraints

All values in input are integers.

1 \leq N, M \leq 2 \times 10^5

0 \leq K \leq N - 1

Input

Input is given from Standard Input in the following format:

N M K

Output

Print the answer.

Sample Input 1

3 2 1

Sample Output 1

6

The following ways to paint the blocks satisfy the conditions: 112, 121, 122, 211, 212, and 221. Here, digits represent the colors of the blocks.

Sample Input 2

100 100 0

Sample Output 2

73074801

Sample Input 3

60522 114575 7559

Sample Output 3

479519525

Solution in Rust (1.42.0) (judge verdict: Accepted)

use std::*;
use std::io::*;
use std::iter::Iterator;
use std::str::FromStr;
#[allow(unused_imports)]
use std::fmt::{Display, Formatter};

#[allow(dead_code)]
fn main() {
  let stdin = stdin();
  let r = &mut BufReader::new(stdin.lock());
  let stdout = stdout();
  let w = &mut BufWriter::new(stdout.lock());
  let stderr = stderr();
  let err = &mut BufWriter::new(stderr.lock());
  run(r, w, err);
  w.flush().unwrap();
  err.flush().unwrap();
}

macro_rules! _ft { () => (impl FnOnce(&mut Cursor<Vec<u8>>, &mut Vec<u8>, &mut Vec<u8>)); }

#[allow(dead_code)]
fn test(input: &str, output: &str, f: _ft!()) {
  let r = &mut Cursor::new(input.as_bytes().to_vec());
  let w: &mut Vec<u8> = &mut Vec::new();
  let err: &mut Vec<u8> = &mut Vec::new();
  f(r, w, err);
  let mut stderr = stderr();
  writeln!(stderr, "{}", String::from_utf8(err.to_vec()).unwrap()).unwrap();
  stderr.flush().ok();
  assert_eq!(String::from_utf8(w.to_vec()).unwrap().trim(), output.trim())
}

#[allow(unused_macros)]
macro_rules! t {
  ($f: ident => $input: expr, $output: expr) => (
    #[test]
    fn $f() { test($input, $output, run); }
  );
}

macro_rules! _display_st {
    ($f: expr; $name: expr, ) => (write!($f, "{}", $name)?);
    ($f: expr; $name: expr) => (_display_st!($f; $name, ));
    ($f: expr; $name: expr, $($rest: expr),+, ) => (
      _display_st!($f; $name);
      write!($f, " ")?;
      _display_st!($f; $($rest, )+);
    );
    ($f: expr; $name: expr, $($rest: expr),+) => (_display_st!($f; $name, $($rest, )+));
}

macro_rules! _st_iter_parse {
  ($iter: expr; $($p: ident : $t: ty),+; ) => (Self {
    $($p: $iter.next().unwrap().parse::<$t>().unwrap(), )+
  });
  ($iter: expr; $($p: ident : $t: ty),+; 1~) => (Self {
    $($p: $iter.next().unwrap().parse::<$t>().unwrap() - 1, )+
  });
}

/// 構造体を作成する
#[allow(unused_macros)]
macro_rules! st {
  ($name: ident => $($p: ident : $t: ty),+; $($rest: tt)*) => (
    struct $name { $($p : $t),+ }
    impl FromStr for $name {
      type Err = ();
      fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        let mut iter = s.split_whitespace();
        Ok(_st_iter_parse!(iter; $($p : $t),+; $($rest)*))
      }
    }
    impl Display for $name {
      fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        _display_st!(f; $(&self.$p, )+);
        Ok(())
      }
    }
  );
  ($name: ident => $($p: ident : $t: ty),+) => (st!($name => $($p : $t),+; ););

  ($name: ident => $($($p: ident),+: $t: ty);+) => (st!($name => $($($p : $t),+),+););
  ($name: ident => $($($p: ident),+: $($t: ty),+);+) => (st!($name => $($($p : $t),+),+););
  ($name: ident => $($p: ident),+: $t: ty) => (st!($name => $($p : $t),+););
  ($name: ident => $($p: ident),+: $($t: ty),+) => (st!($name => $($p : $t),+););

  ($name: ident => $($($p: ident),+: $t: ty);+; $($rest: tt)*) => (
    st!($name => $($($p : $t),+),+; $($rest)*);
  );
  ($name: ident => $($($p: ident),+: $($t: ty),+);+; $($rest: tt)*) => (
    st!($name => $($($p : $t),+),+; $($rest)*);
  );
  ($name: ident => $($p: ident),+: $t: ty; $($rest: tt)*) => (
    st!($name => $($p : $t),+; $($rest)*);
  );
  ($name: ident => $($p: ident),+: $($t: ty),+; $($rest: tt)*) => (
    st!($name => $($p : $t),+; $($rest)*);
  );
}

fn _read_iter<R: Read>(reader: &mut R) -> impl Iterator<Item=char> + '_ {
  reader.by_ref()
    .bytes()
    .map(|c| c.unwrap() as char)
    .skip_while(|c| c.is_whitespace())
}

#[allow(dead_code)]
fn read<F: FromStr, R: Read>(reader: &mut R) -> F {
  let str = _read_iter(reader).take_while(|c| !c.is_whitespace()).collect::<String>();
  str.parse::<F>().ok().unwrap()
}

#[allow(dead_code)]
fn read_line<F: FromStr, R: Read>(reader: &mut R) -> F {
  let str = _read_iter(reader).take_while(|c| c != &'\n').collect::<String>();
  let str = if str.ends_with('\r') { &str[0..str.len() - 1] } else { &str };
  str.parse::<F>().ok().unwrap()
}

#[allow(dead_code)]
fn read1<R: Read, T>(reader: &mut R, mut f: impl FnMut(char) -> T) -> T {
  f(_read_iter(reader).next().unwrap())
}

#[allow(dead_code)]
fn read1_line<R: Read, T>(reader: &mut R, f: impl FnMut(char) -> T) -> Vec<T> {
  _read_iter(reader).take_while(|c| c != &'\n').map(f).collect::<Vec<_>>()
}

/// 1要素読む
#[allow(unused_macros)]
macro_rules! r {
  ($stream: expr) => (read::<String, _>($stream));
  ($stream: expr, ) => (r!($stream));
  ($stream: expr; ) => (r!($stream));

  ($stream: expr; $t: ty) => (read::<$t, _>($stream));
  ($stream: expr; $t: ty; 1~) => (r!($stream; $t) - 1);

  ($stream: expr; $($t: ty),+) => (($(r!($stream; $t)),*));
  ($stream: expr; $($t: ty),+; 1~) => (($(r!($stream; $t) - 1),*));

  ($stream: expr; $t: ty; $n: expr) => (
    (0..$n).map(|_| r!($stream; $t)).collect::<Vec<_>>()
  );
  ($stream: expr; $t: ty; $n: expr; 1~) => (
    (0..$n).map(|_| r!($stream; $t) - 1).collect::<Vec<_>>()
  );

  ($stream: expr; $t: ty; $h: expr, $w: expr) => (
    (0..$h).map(|_| (0..$w).map(|_| r!($stream; $t)).collect::<Vec<_>>()).collect::<Vec<_>>()
  );
  ($stream: expr; $t: ty; $h: expr, $w: expr; 1~) => (
    (0..$h).map(|_| (0..$w).map(|_| r!($stream; $t) - 1).collect::<Vec<_>>()).collect::<Vec<_>>()
  );
}

/// 1文字読む
#[allow(unused_macros)]
macro_rules! r1 {
  ($stream: expr) => (read1($stream, |c| c));
  ($stream: expr, ) => (r!($stream));
  ($stream: expr; ) => (r!($stream));
  ($stream: expr; $f: expr) => (read1($stream, $f));
  ($stream: expr; $f: expr; ) => (r1!($stream, $f));
  ($stream: expr; $f: expr; $n: expr) => ((0..$n).map(|_| r1!($stream; $f)).collect::<Vec<_>>());
  ($stream: expr; $f: expr; $h: expr, $w: expr) => (
    (0..$h).map(|_| (0..$w).map(|_| r1!($stream; $f)).collect::<Vec<_>>()).collect::<Vec<_>>()
  );

  ($stream: expr; @$c: tt; $($tt: tt)*) => (
   r1!($stream; |c| c == stringify!($c).chars().next().unwrap(); $($tt)*)
  );
  ($stream: expr; @$c: tt/$_c: tt; $($tt: tt)*) => (r1!($stream; @$c; $($tt)*));
}

/// 1行読む
#[allow(unused_macros)]
macro_rules! rl {
  ($stream: expr) => (read_line::<String, _>($stream));
  ($stream: expr, ) => (r!($stream));
  ($stream: expr; ) => (r!($stream));
  ($stream: expr; $t: ty) => (read_line::<$t,  _>($stream));
  ($stream: expr; $t: ty; $n: expr) => ((0..$n).map(|_| rl!($stream; $t)).collect::<Vec<_>>());
}

macro_rules! _writes {
  ($stream: expr; $arg0: expr, $($arg: expr),*) => ({
    write!($stream, "{}", $arg0).ok();
    $(write!($stream, " {}", $arg).ok();)*
  });
}

/// 変数を出力
#[allow(unused_macros)]
macro_rules! w {
  ($stream: expr) => (write!($stream, " ").ok());
  ($stream: expr; ) => (w!($stream));
  ($stream: expr, ) => (w!($stream));

  ($stream: expr; $arg: expr) => (write!($stream, "{}", $arg).ok());
  ($stream: expr; $arg: expr, ) => (w!($stream; $arg));

  ($stream: expr; $arg0: expr, $($arg: expr),+) => (_writes!($stream; $arg0, $($arg),+));
  ($stream: expr; $arg0: expr, $($arg: expr),+, ) => (w!($stream; $arg0, $($arg),*));

  ($stream: expr, $($arg: tt)*) => (write!($stream, $($arg)*).ok());
}

/// 変数を改行付きで出力
#[allow(unused_macros)]
macro_rules! wl {
  ($stream: expr) => (writeln!($stream).ok());
  ($stream: expr, ) => (wl!($stream));
  ($stream: expr; ) => (wl!($stream));

  ($stream: expr; $arg: expr) => (writeln!($stream, "{}", $arg).ok());
  ($stream: expr; $arg: expr, ) => (wl!($stream; $arg));

  ($stream: expr; $arg0: expr, $($arg: expr),+) => ({
    _writes!($stream; $arg0, $($arg),+);
    wl!($stream)
  });
  ($stream: expr; $arg0: expr, $($arg: expr),+, ) => (wl!($stream; $arg0, $($arg),*));

  ($stream: expr, $($arg: tt)*) => (writeln!($stream, $($arg)*).ok());
}

/// ベクタを出力
#[allow(unused_macros)]
macro_rules! w_vec {
  ($stream: expr; $vec: expr) => (w_vec!($stream; $vec; $vec.len()));
  ($stream: expr; $vec: expr; $($tt: tt)*) => (w_vec!($stream; $vec => |e| e, " "; $($tt)*));

  ($stream: expr; $vec: expr => $f: expr) => (w_vec!($stream; $vec => $f; $vec.len()));
  ($stream: expr; $vec: expr => $f: expr; $($tt: tt)*) => (
    w_vec!($stream; $vec => $f, ""; $($tt)*)
  );

  ($stream: expr; $vec: expr => $f: expr, $del: expr; $n: expr) => (
    w!($stream; $f($vec[0]));
    for i in 1..$n { w!($stream, "{}{}", $del, $f($vec[i as usize])); }
    wl!($stream);
  );
  ($stream: expr; $vec: expr => $f: expr, $del: expr; $h: expr, $w: expr) => (
    for i in 0..$h { w_vec!($stream; $vec[i as usize] => $f, $del; $w); }
  );

  ($stream: expr; $vec: expr => String) => (w_vec!($stream; $vec => |c| c as char; $vec.len()));
  ($stream: expr; $vec: expr => String; $($tt: tt)*) => (
    w_vec!($stream; $vec => |c| c as char; $($tt)*)
  );

  ($stream: expr; $vec: expr => @$c_t: tt/$c_f: tt) => (
    w_vec!($stream; $vec => @$c_t/$c_f; $vec.len())
  );
  ($stream: expr; $vec: expr => @$c_t: tt/$c_f: tt; $($tt: tt)*) => (
    w_vec!($stream; $vec => |e| if e {stringify!($c_t)} else {stringify!($c_f)}; $($tt)*)
  );
}

/// ベクタを改行付きで出力
#[allow(unused_macros)]
macro_rules! wl_vec {
  ($stream: expr; $vec: expr) => (w_vec!($stream; $vec => |e| e, "\n"; $vec.len()));
  ($stream: expr; $vec: expr; $($tt: tt)*) => (w_vec!($stream; $vec => |e| e, "\n"; $($tt)*));
  ($stream: expr; $vec: expr => $f: expr) => (w_vec!($stream; $vec => $f, "\n"; $vec.len()));
  ($stream: expr; $vec: expr => $f: expr; $($tt: tt)*) => (
    w_vec!($stream; $vec => $f, "\n"; $($tt)*)
  );

  ($stream: expr; $vec: expr => 1~) => (wl_vec!($stream; $vec => |e| e + 1; $vec.len()));
  ($stream: expr; $vec: expr => 1~; $($tt: tt)*) => (
    w_vec!($stream; $vec => |e| e + 1, "\n"; $($tt)*)
  );

  ($stream: expr; $vec: expr => String) => (
    wl_vec!($stream; $vec => |c| c as char, "\n"; $vec.len())
  );
  ($stream: expr; $vec: expr => String; $($tt: tt)*) => (
    w_vec!($stream; $vec => |c| c as char, "\n"; $($tt)*)
  );

  ($stream: expr; $vec: expr => @$c_t: tt/$c_f: tt) => (
    wl_vec!($stream; $vec => @$c_t/$c_f; $vec.len())
  );
  ($stream: expr; $vec: expr => @$c_t: tt/$c_f: tt; $($tt: tt)*) => (
    w_vec!($stream; $vec => |e| if e {stringify!($c_t)} else {stringify!($c_f)}, "\n"; $($tt)*)
  );
}

/// 早期リターン
#[allow(unused_macros)]
macro_rules! early { ($($t: tt)*) => ({ w!($($t)*); return; }); }

/// 配列の初期化
#[allow(unused_macros)]
macro_rules! v {
  ($elem: expr; $n: expr) => (vec![$elem; $n as usize]);
  ($elem: expr; $h: expr, $w: expr) => (vec![vec![$elem; $w as usize]; $h as usize]);
}

// start: Copied Libraries

fn pow_mod(mut a: i64, mut n: i64, m: i64) -> i64 {
  let mut res: i64 = 1;
  while n > 0 {
    if n & 1 == 1 {
      res = res * a % m;
    }
    a = a * a % m;
    n >>= 1;
  }
  res
}

fn extended_euclidean(u: i64, v: i64) -> i64 {
  let mut r0 = u;
  let mut r1 = v;
  let mut s0 = 1;
  let mut s1 = 0;
  let mut t0 = 0;
  let mut t1 = 1;
  while r1 != 0 {
    let q = r0 / r1;
    let r = r0 - q * r1;
    let s = s0 - q * s1;
    let t = t0 - q * t1;
    r0 = r1;
    s0 = s1;
    t0 = t1;
    r1 = r;
    s1 = s;
    t1 = t;
  }
  if t0 < 0 {
    t0 + u
  } else {
    t0
  }
}

fn combination(mut n: i64, r: i64, m: i64) -> i64 {
  let mut upe = 1;
  let mut dow = 1;
  for i in 1..r + 1 {
    upe = upe * n % m;
    dow = dow * i % m;

    n -= 1;
  }
  upe * pow_mod(dow, m - 2, m) % m
}
// end: Copied Libraries

#[allow(unused_variables)]
fn run<R: Read, W: Write, E: Write>(r_: &mut R, w_: &mut W, err: &mut E) {
  let (n, m, k) = r!(r_; usize, usize, usize);
  let c = 998244353usize;

  let mut sum = 0usize;
  let mut comb_up = 1usize;
  let mut comb_down = 1usize;

  for x in 0..k + 1 {
    let mut ans = pow_mod((m - 1) as i64, (n - x - 1) as i64, c as i64) as usize;
    ans = (ans * m) % c;
    // wl!(err; comb_up, "/", comb_down);
    let comb = (comb_up * extended_euclidean(c as i64, comb_down as i64) as usize) % c;
    // ans = (ans * combination(n - 1, x, c)) % c;
    // w!(err; comb, "<-> ");
    // let comb = combination((n - 1) as i64, x as i64, c as i64) as usize;
    // wl!(err; comb);
    ans = (ans * comb) % c;
    sum += ans;
    sum %= c;

    comb_up = (comb_up * (n - x - 1)) % c;
    comb_down = (comb_down * (x + 1)) % c;

  }
  w!(w_; sum);
}

t!(te1 => r"3 2 1", r"6");
t!(te2 => r"100 100 0", r"73074801");
t!(te3 => r"60522 114575 7559", r"479519525");