use std::fmt::Debug; fn main() { let stdin = std::io::stdin(); let mut rd = ProconReader::new(stdin.lock()); let n: usize = rd.get(); let a: Vec = (0..n).map(|_| { rd.get() }).collect(); let mo: usize = 998244353; use mint::Mint; let mut ans = Mint::zero(mo); let mut left_cnt = vec![0; n]; // 0..j の範囲で a[j] より大きい数の個数 let mut left_sum = vec![Mint::zero(mo); n]; // 0..j の範囲で a[j] より大きい数の総和 let mut right_cnt = vec![0; n]; // (j+1)..n の範囲で a[j] より小さい数の個数 let mut right_sum = vec![Mint::zero(mo); n]; // (j+1)..n の範囲で a[j] より小さい数の総和 { let mut ai = a.iter().zip(0..n).map(|(&x, i)| (x, i)).collect::>(); ai.sort_by(|(x, i), (y, j)| { if x == y { i.cmp(j) } else { x.cmp(y) } }); let mut seg = SegmentTree::new(n, 0usize, |x, y| x + y); let mut teg = SegmentTree::new(n, Mint::zero(mo), |x, y| x + y); for (x, i) in ai { right_cnt[i] = seg.fold((i + 1)..n); right_sum[i] = teg.fold((i + 1)..n); seg.update(i, 1); teg.update(i, Mint::new(x, mo)); } } { let mut ai = a.iter().zip(0..n).map(|(&x, i)| (x, i)).collect::>(); ai.sort_by(|(x, i), (y, j)| { if x == y { j.cmp(i) } else { y.cmp(x) } }); let mut seg = SegmentTree::new(n, 0usize, |x, y| x + y); let mut teg = SegmentTree::new(n, Mint::zero(mo), |x, y| x + y); for (x, i) in ai { left_cnt[i] = seg.fold(0..i); left_sum[i] = teg.fold(0..i); seg.update(i, 1); teg.update(i, Mint::new(x, mo)); } } macro_rules! add { ($a:expr, $b:expr) => { $a = $a + $b; } } for j in 0..n { let l_c = left_cnt[j]; let r_c = right_cnt[j]; let l_s = left_sum[j]; let r_s = right_sum[j]; add!(ans, a[j] * l_c * r_c % mo); add!(ans, l_s * r_c); add!(ans, r_s * l_c); } println!("{}", ans); } struct SegmentTree { n: usize, dat: Vec, e: T, multiply: F, } #[allow(dead_code)] impl SegmentTree where T: Clone + Copy + Debug, F: Fn(T, T) -> T, { fn new(n: usize, e: T, multiply: F) -> Self { let n = n.next_power_of_two(); Self { n, dat: vec![e; n * 2 - 1], e, multiply, } } fn get(&self, i: usize) -> T { self.dat[i + self.n - 1] } fn update(&mut self, i: usize, x: T) { let mut k = i + self.n - 1; self.dat[k] = x; while k > 0 { k = (k - 1) / 2; self.dat[k] = (self.multiply)(self.dat[k * 2 + 1], self.dat[k * 2 + 2]); } } fn fold(&self, range: std::ops::Range) -> T { self._fold(&range, 0, 0..self.n) } fn _fold( &self, range: &std::ops::Range, i: usize, i_range: std::ops::Range, ) -> T { if range.end <= i_range.start || i_range.end <= range.start { return self.e; } if range.start <= i_range.start && i_range.end <= range.end { return self.dat[i]; } let m = (i_range.start + i_range.end) / 2; (self.multiply)( self._fold(range, i * 2 + 1, i_range.start..m), self._fold(range, i * 2 + 2, m..i_range.end), ) } } #[allow(dead_code)] mod mint { use std::ops::{Add, BitAnd, Div, Mul, Rem, Shr, Sub}; #[derive(Copy, Clone, Debug)] pub struct Mint { x: T, mo: T, } impl Mint where T: Copy, { pub fn new(x: T, mo: T) -> Mint { Mint { x, mo } } } impl Mint where T: Copy, { pub fn val(&self) -> T { self.x } pub fn mo(&self) -> T { self.mo } } impl Add for Mint where T: Copy, T: Add, T: Rem, { type Output = Mint; fn add(self, rhs: T) -> Mint { Mint::new((self.val() + rhs % self.mo()) % self.mo(), self.mo()) } } impl Add> for Mint where T: Copy, Mint: Add>, { type Output = Mint; fn add(self, rhs: Mint) -> Mint { self + rhs.val() } } impl Sub for Mint where T: Copy, T: Add, T: Sub, T: Rem, { type Output = Mint; fn sub(self, rhs: T) -> Mint { Mint::new( (self.val() + self.mo() - rhs % self.mo()) % self.mo(), self.mo(), ) } } impl Sub> for Mint where T: Copy, Mint: Sub>, { type Output = Mint; fn sub(self, rhs: Mint) -> Mint { self - rhs.val() } } impl Mul for Mint where T: Copy, T: Mul, T: Rem, { type Output = Mint; fn mul(self, rhs: T) -> Mint { Mint::new((self.val() * rhs % self.mo()) % self.mo(), self.mo()) } } impl Mul> for Mint where T: Copy, Mint: Mul>, { type Output = Mint; fn mul(self, rhs: Mint) -> Mint { self * rhs.val() } } impl Mint where T: Copy, T: Sub, T: Div, T: PartialOrd, T: PartialEq, T: BitAnd, T: Shr, Mint: Mul>, { pub fn pow(self, y: T) -> Mint { let one = self.mo() / self.mo(); let zero = self.mo() - self.mo(); let mut res = Mint::one(self.mo()); let mut base = self; let mut exp = y; while exp > zero { if (exp & one) == one { res = res * base; } base = base * base; exp = exp >> one; } res } } impl Div for Mint where T: Copy, T: Sub, T: Div, T: PartialOrd, T: PartialEq, T: BitAnd, T: Shr, Mint: Mul>, { type Output = Mint; fn div(self, rhs: T) -> Mint { let one = self.mo() / self.mo(); self * Mint::new(rhs, self.mo()).pow(self.mo() - one - one) } } impl Div> for Mint where T: Copy, Mint: Div>, { type Output = Mint; fn div(self, rhs: Mint) -> Mint { self / rhs.val() } } impl Mint where T: Copy, T: Div, Mint: Div>, { pub fn inv(self) -> Mint { Mint::one(self.mo()) / self } } impl std::fmt::Display for Mint where T: Copy + std::fmt::Display, { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.val()) } } impl Mint where T: Copy, T: Sub, { pub fn zero(mo: T) -> Mint { Mint { x: mo - mo, mo } } } impl Mint where T: Copy, T: Div, { pub fn one(mo: T) -> Mint { Mint { x: mo / mo, mo } } } } pub struct ProconReader { reader: R, } impl ProconReader { pub fn new(reader: R) -> Self { Self { reader } } pub fn get(&mut self) -> T { use std::io::Read; let buf = self .reader .by_ref() .bytes() .map(|b| b.unwrap()) .skip_while(|&byte| byte == b' ' || byte == b'\n' || byte == b'\r') .take_while(|&byte| byte != b' ' && byte != b'\n' && byte != b'\r') .collect::>(); std::str::from_utf8(&buf) .unwrap() .parse() .ok() .expect("Parse Error.") } }