use proconio::input; const P: u64 = 998_244_353; type Fp = fp::Fp
;
fn main() {
input! {
n: usize,
k: u64,
a: [u64; n],
}
let ans = if a.iter().all(|&x| x < k) {
fp!(0)
} else {
(fp!(k).pow(n as u64) - fp!(k - 1).pow(n as u64))
/ a.iter().map(|&x| fp!(x)).product:: {
pub fn new(length: usize) -> Self {
let mut fact = vec![Fp:: ::new(1); length + 1];
let mut inv_fact = vec![Fp:: ::new(1); length + 1];
for i in 1..=length {
fact[i] = fact[i - 1] * Fp:: ::new(i as u64);
}
inv_fact[length] = fact[length].inv();
for i in (1..=length).rev() {
inv_fact[i - 1] = inv_fact[i] * Fp:: ::new(i as u64);
}
Self { fact, inv_fact }
}
pub fn fact(&self, n: usize) -> Fp {
self.fact[n]
}
pub fn inv_fact(&self, n: usize) -> Fp {
self.inv_fact[n]
}
pub fn falling(&self, n: usize, k: usize) -> Fp {
if n < k {
Fp::new(0)
} else {
self.fact[n] * self.inv_fact[n - k]
}
}
pub fn binom(&self, n: usize, k: usize) -> Fp {
assert!(n < self.fact.len());
if k > n {
Fp::new(0)
} else {
self.fact[n] * self.inv_fact[n - k] * self.inv_fact[k]
}
}
pub fn multinom(&self, a: &[usize]) -> Fp {
let n = a.iter().sum:: {
assert!(n < self.fact.len());
if k < 0 {
return Fp::new(0);
}
let k = k as usize;
if n < k {
Fp::new(0)
} else {
self.fact[n] * self.inv_fact[n - k] * self.inv_fact[k]
}
}
pub fn multiset_number(&self, n: usize, k: usize) -> Fp {
if (n, k) == (0, 0) {
Fp::new(1)
} else {
self.binom(n + k - 1, k)
}
}
}
impl {
type Output = Fp ;
fn index(&self, index: usize) -> &Self::Output {
&self.fact[index]
}
}
}
mod fourier {
use super::mod_inv;
use super::Fp;
use super::PrimitiveRoot;
const P1: u64 = 924_844_033;
const P2: u64 = 998_244_353;
const P3: u64 = 1_012_924_417;
type F1 = Fp ]>, b: impl AsRef<[Fp ]>) -> Vec ,
{
let a = a.as_ref();
let b = b.as_ref();
if a.is_empty() || b.is_empty() {
return vec![];
}
let mut a = a.to_vec();
let mut b = b.to_vec();
let n = a.len() + b.len() - 1;
let len = n.next_power_of_two();
a.resize(len, Fp::new(0));
b.resize(len, Fp::new(0));
fft(&mut a);
fft(&mut b);
for (a, b) in a.iter_mut().zip(b.iter()) {
*a *= *b;
}
ifft(&mut a);
a.truncate(n);
a
}
pub fn any_mod_fps_mul ], b: &[Fp ]) -> Vec ])
where
(): PrimitiveRoot ,
{
let n = f.len();
assert!(n.is_power_of_two());
assert!((P - 1) % n as u64 == 0);
let mut root = <() as PrimitiveRoot >::VALUE.pow((P - 1) / f.len() as u64);
let fourth = <() as PrimitiveRoot >::VALUE.pow((P - 1) / 4);
let mut fft_len = n;
while 4 <= fft_len {
let quarter = fft_len / 4;
for f in f.chunks_mut(fft_len) {
let mut c = Fp::new(1);
for (((i, j), k), l) in (0..)
.zip(quarter..)
.zip(quarter * 2..)
.zip(quarter * 3..)
.take(quarter)
{
let c2 = c * c;
let x = f[i] + f[k];
let y = f[j] + f[l];
let z = f[i] - f[k];
let w = fourth * (f[j] - f[l]);
f[i] = x + y;
f[j] = c2 * (x - y);
f[k] = c * (z + w);
f[l] = c2 * c * (z - w);
c *= root;
}
}
root *= root;
root *= root;
fft_len = quarter;
}
if fft_len == 2 {
for f in f.chunks_mut(2) {
let x = f[0];
let y = f[1];
f[0] = x + y;
f[1] = x - y;
}
}
}
pub fn ifft ])
where
(): PrimitiveRoot ,
{
let n = f.len();
assert!(n.is_power_of_two());
let root = <() as PrimitiveRoot >::VALUE.pow((P - 1) / f.len() as u64);
let mut roots = std::iter::successors(Some(root.inv()), |x| Some(x * x))
.take(n.trailing_zeros() as usize + 1)
.collect:: >::VALUE.pow((P - 1) / 4).inv();
let mut quarter = 1_usize;
if n.trailing_zeros() % 2 == 1 {
for f in f.chunks_mut(2) {
let x = f[0];
let y = f[1];
f[0] = x + y;
f[1] = x - y;
}
quarter = 2;
}
while quarter != n {
let fft_len = quarter * 4;
let root = roots[fft_len.trailing_zeros() as usize];
for f in f.chunks_mut(fft_len) {
let mut c = Fp::new(1);
for (((i, j), k), l) in (0..)
.zip(quarter..)
.zip(quarter * 2..)
.zip(quarter * 3..)
.take(quarter)
{
let c2 = c * c;
let x = f[i] + c2 * f[j];
let y = f[i] - c2 * f[j];
let z = c * (f[k] + c2 * f[l]);
let w = fourth * c * (f[k] - c2 * f[l]);
f[i] = x + z;
f[j] = y + w;
f[k] = x - z;
f[l] = y - w;
c *= root;
}
}
quarter = fft_len;
}
let d = Fp::from(f.len()).inv();
f.iter_mut().for_each(|x| *x *= d);
}
fn garner {
let (x1, x2, x3) = (x1.value(), x2.value(), x3.value());
let x2 = ((x2 + (P2 - x1)) * mod_inv:: ,
zero: u64,
}
impl {
pub fn one() -> Self {
Self {
unit: Fp::new(1),
zero: 0,
}
}
pub fn new(unit: u64) -> Self {
let mut self_ = Self::one();
self_ *= unit;
self_
}
pub fn value(&self) -> Fp {
if self.zero > 0 {
Fp::new(0)
} else {
self.unit
}
}
}
impl {
fn mul_assign(&mut self, mut rhs: u64) {
assert_ne!(rhs, 0);
while rhs % P == 0 {
rhs /= P;
self.zero += 1;
}
self.unit *= Fp::new(rhs);
}
}
impl {
fn div_assign(&mut self, mut rhs: u64) {
assert_ne!(rhs, 0);
while rhs % P == 0 {
rhs /= P;
self.zero -= 1;
}
self.unit /= Fp::new(rhs);
}
}
}
use ext_gcd::mod_inv;
pub use factorial::Factorial;
pub use fourier::any_mod_fps_mul;
pub use fourier::fft;
pub use fourier::fps_mul;
pub use fourier::ifft;
use std::iter::Product;
use std::iter::Sum;
use std::mem::swap;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::SubAssign;
pub use zeroed::Zeroed;
#[macro_export]
macro_rules! fp {
($value:expr) => {
$crate::fp::Fp::from($value)
};
($value:expr; mod $p:expr) => {
$crate::fp::Fp::<$p>::from($value)
};
}
pub trait PrimitiveRoot ;
}
impl PrimitiveRoot<998_244_353> for () {
const VALUE: Fp<998_244_353> = Fp::new(3);
}
impl PrimitiveRoot<1_012_924_417> for () {
const VALUE: Fp<1_012_924_417> = Fp::new(5);
}
impl PrimitiveRoot<924_844_033> for () {
const VALUE: Fp<924_844_033> = Fp::new(5);
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Fp {
pub const fn new(value: u64) -> Self {
Self { value: value % P }
}
pub const fn value(self) -> u64 {
self.value
}
pub const fn m1pow(exp: usize) -> Self {
match exp % 2 {
0 => Self { value: 1 },
1 => Self { value: P - 1 },
_ => unreachable!(),
}
}
pub fn inv(self) -> Self {
Self {
value: mod_inv:: (self.value),
}
}
pub fn pow(self, mut exp: u64) -> Self {
let mut result = Self::new(1);
let mut base = self;
while exp > 0 {
if exp & 1 == 1 {
result *= base;
}
base *= base;
exp >>= 1;
}
result
}
pub fn sign(pow: usize) -> Self {
Self::new(if pow % 2 == 0 { 1 } else { P - 1 })
}
}
impl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
pub fn berlekamp_massey_fp(a: i64, p: i64) -> [i64; 2] {
let mut u0 = 0_i64;
let mut v0 = 1_i64;
let mut w0 = a * u0 + p * v0;
let mut u1 = 1_i64;
let mut v1 = 0_i64;
let mut w1 = a * u1 + p * v1;
while p <= w0 * w0 {
let q = w0 / w1;
u0 -= q * u1;
v0 -= q * v1;
w0 -= q * w1;
swap(&mut u0, &mut u1);
swap(&mut v0, &mut v1);
swap(&mut w0, &mut w1);
}
[w0, u0]
}
if self.value == 0 {
return write!(f, "0");
}
let [mut num, mut den] = berlekamp_massey_fp(self.value as i64, P as i64);
if den < 0 {
num = -num;
den = -den;
}
if den == 1 {
write!(f, "{num}")
} else {
write!(f, "{num}/{den}")
}
}
}
impl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value())
}
}
macro_rules! impl_from_signed {
($($t:ty),*) => {
$(
impl {
fn from(x: $t) -> Self {
if x < 0 {
-Self::new((P as i64 - x as i64) as u64)
} else {
Self::new(x as u64)
}
}
}
)*
};
}
impl_from_signed!(i8, i16, i32, i64, i128, isize);
macro_rules! impl_from_unsigned {
($($t:ty),*) => {
$(
impl {
fn from(x: $t) -> Self { Self::new(x as u64) }
}
)*
};
}
impl_from_unsigned!(u8, u16, u32, u64, u128, usize);
impl {
fn add_assign(&mut self, rhs: Fp ) {
self.value += rhs.value;
if self.value >= P {
self.value -= P;
}
}
}
impl {
fn sub_assign(&mut self, rhs: Fp ) {
if self.value < rhs.value {
self.value += P;
}
self.value -= rhs.value;
}
}
impl {
fn mul_assign(&mut self, rhs: Fp ) {
self.value = self.value * rhs.value % P;
}
}
#[allow(clippy::suspicious_op_assign_impl)]
impl {
fn div_assign(&mut self, rhs: Fp ) {
*self *= rhs.inv();
}
}
macro_rules! fp_forward_ops {
($(
$trait:ident,
$trait_assign:ident,
$fn:ident,
$fn_assign:ident,
)*) => {$(
impl > for Fp {
fn $fn_assign(&mut self, rhs: &Fp ) {
self.$fn_assign(*rhs);
}
}
impl {
type Output = Fp ;
fn $fn(mut self, rhs: T) -> Self::Output {
self.$fn_assign(rhs.into());
self
}
}
impl > for Fp {
type Output = Fp ;
fn $fn(self, rhs: &Fp ) -> Self::Output {
self.$fn(*rhs)
}
}
impl {
type Output = Fp ;
fn $fn(self, rhs: T) -> Self::Output {
(*self).$fn(rhs.into())
}
}
impl > for &Fp {
type Output = Fp ;
fn $fn(self, rhs: &Fp ) -> Self::Output {
(*self).$fn(*rhs)
}
}
)*};
}
fp_forward_ops! {
Add, AddAssign, add, add_assign,
Sub, SubAssign, sub, sub_assign,
Mul, MulAssign, mul, mul_assign,
Div, DivAssign, div, div_assign,
}
impl {
type Output = Fp ;
fn neg(mut self) -> Self::Output {
if self.value > 0 {
self.value = P - self.value;
}
self
}
}
impl {
fn sum {
fn sum {
fn product {
fn product