#include using namespace std; #ifdef LOCAL_ void debug_out() {cerr << endl;} template void debug_out(Head H,Tail... T){cerr << ' ' << H; debug_out(T...);} #define debug(...) cerr << 'L' << __LINE__ << " [" << #__VA_ARGS__ << "]:",debug_out(__VA_ARGS__) #define dump(x) cerr << 'L' << __LINE__ << " " << #x << " = " << (x) << endl; #else #define debug(...) (void(0)) #define dump(x) (void(0)) #endif #define rep(i,n) for (int i = 0; i < (int)(n); i ++) #define irep(i,n) for (int i = (int)(n) - 1;i >= 0;--i) using ll = long long; using PL = pair; using P = pair; constexpr int INF = 1000000000; constexpr long long HINF = 100000'00000'00000; constexpr long long MOD = 998244353; constexpr double EPS = 1e-4; constexpr double PI = 3.14159265358979; #pragma region Macros template ostream &operator<<(ostream &os,const pair &p) { os << '(' << p.first << ',' << p.second << ')'; return os; } template ostream &operator<<(ostream &os,const vector &v) { os << '['; for (auto &e:v) {os << e << ',';} os << ']'; return os; } // grid searh const int dy[8] = {-1,0,1,0,-1,-1,1,1}; const int dx[8] = {0,1,0,-1,-1,1,-1,1}; bool IN(int y,int x,int H,int W) {return (0 <= y)&&(y < H)&&(0 <= x)&&(x < W);} #pragma endregion template struct BinaryIndexedTree { int N,power = 1; vector bit; BinaryIndexedTree(int N = 0): N(N){ bit.assign(N + 1,0); while (power <= N) power <<= 1; //power > N } void build(const vector &A) { for (int i = 1;i <= N; ++i) add(i,A[i - 1]); } // add x to a[i] void add(int i,T x) { for (int idx = i; idx <= N; idx += (idx & -idx)) { bit[idx] += x; } } // return a[1] + a[2] + a[3] + .. + a[k] T sum(int k) { T ret = 0; for (int idx = k; idx > 0; idx -= (idx & -idx)) { ret += bit[idx]; } return ret; } // return a[l] + a[l + 1] + a[l + 2] + .. + a[r - 1] T sum(int l,int r) { return sum(r - 1) - sum(l - 1); } // return min index s.t. a[1] + a[2] + a[3] + .. + a[x] >= w int lower_bound(T w) { if (w <= 0) return 0; int x = 0; for (int r = power; r > 0; r >>= 1) { if (x + r <= N && bit[x + r] < w) { w -= bit[x + r]; x += r; } } return x + 1; } }; template struct ModInt { long long x; ModInt(long long x = 0) :x((x%Modulus + Modulus)%Modulus) {} constexpr ModInt &operator+=(const ModInt a) {if ((x += a.x) >= Modulus) x -= Modulus; return *this;} constexpr ModInt &operator-=(const ModInt a) {if ((x += Modulus - a.x) >= Modulus) x -= Modulus; return *this;} constexpr ModInt &operator*=(const ModInt a) {(x *= a.x) %= Modulus; return *this;} constexpr ModInt &operator/=(const ModInt a) {return *this *= a.inverse();} constexpr ModInt operator+(const ModInt a) const {return ModInt(*this) += a.x;} constexpr ModInt operator-(const ModInt a) const {return ModInt(*this) -= a.x;} constexpr ModInt operator*(const ModInt a) const {return ModInt(*this) *= a.x;} constexpr ModInt operator/(const ModInt a) const {return ModInt(*this) /= a.x;} friend constexpr ostream& operator<<(ostream& os,const ModInt& a) {return os << a.x;} friend constexpr istream& operator>>(istream& is,ModInt& a) {return is >> a.x;} ModInt inverse() const {// x ^ (-1) long long a = x,b = Modulus,p = 1,q = 0; while (b) {long long d = a/b; a -= d*b; swap(a,b); p -= d*q; swap(p,q);} return ModInt(p); } ModInt pow(long long N) {// x ^ N ModInt a = 1; while (N) { if (N&1) a *= *this; *this *= *this; N >>= 1; } return a; } }; using mint = ModInt<998244353>; map compress(vector A) { sort(A.begin(),A.end()); A.erase(unique(A.begin(),A.end()),A.end()); map mp; rep(i,A.size()) mp[A[i]] = i; return mp; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int N; cin >> N; vector A(N); rep(i,N) cin >> A[i]; auto mp = compress(A); int M = mp.size(); vector> B(M); rep(i,N) { int idx = mp[A[i]]; B[idx].push_back(i); } vector cntL(N),cntR(N); vector left(N),right(N); mint tot = 0; int bf = 0; BinaryIndexedTree bit(N); BinaryIndexedTree idx(N); rep(i,M) { for (int j:B[i]) { left[j] = tot - bit.sum(j+1); cntL[j] = bf - idx.sum(j+1); } for (int j:B[i]) { bit.add(j+1,mint(A[j])); idx.add(j+1,1); tot += A[j]; ++bf; } } BinaryIndexedTree bit2(N); BinaryIndexedTree idx2(N); irep(i,M) { for (int j:B[i]) { right[j] = bit2.sum(j+1); cntR[j] = idx2.sum(j+1); } for (int j:B[i]) { bit2.add(j+1,mint(A[j])); idx2.add(j+1,1); } } mint ans = 0; rep(i,N) { ans += cntL[i]*cntR[i]%MOD*A[i]; if (cntL[i] > 0 && cntR[i] > 0) { ans += right[i]*cntL[i]; ans += left[i]*cntR[i]; } } cout << ans << '\n'; return 0; }