一直没调出来,但是对拍也没错/dk/dk
//#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<stack>
#include<vector>
//#include<conio.h>
#include<string>
#include<map>
#include<cstdlib>
#include<queue>
#include<math.h>
#include<time.h>
#include<set>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
using namespace std;
using std::cin;
using std::cout;
using std::endl;
namespace IN{
const int MAX_INPUT = 1000000;
#define getc() (p1==p2&&(p2=(p1=buf)+inbuf->sgetn(buf,MAX_INPUT),p1==p2)?EOF:*p1++)
char buf[MAX_INPUT],*p1,*p2;
template<typename T>inline bool read(T &x) {
static std::streambuf *inbuf=cin.rdbuf();
x=0;
register int f=0,flag=false;
register char ch=getc();
while(!isdigit(ch)){
if (ch=='-') f=1;
ch=getc();
}
if(isdigit(ch)) x=x*10+ch-'0',ch=getc(),flag=true;
while(isdigit(ch)) {
x=x*10+ch-48;
ch=getc();
}
x=f?-x:x;
return flag;
}
template<typename T,typename ...Args>inline bool read(T& a,Args& ...args) {
return read(a)&&read(args...);
}
#undef getc
}
namespace OUT{
template<typename T>inline void put(T x){
static std::streambuf *outbuf=cout.rdbuf();
static char stack[21];
static int top=0;
if(x<0){
outbuf->sputc('-');
x=-x;
}
if(!x){
outbuf->sputc('0');
outbuf->sputc('\n');
return;
}
while(x){
stack[++top]=x%10+'0';
x/=10;
}
while(top){
outbuf->sputc(stack[top]);
--top;
}
outbuf->sputc('\n');
}
inline void putc(const char ch){
static std::streambuf *outbuf=cout.rdbuf();
outbuf->sputc(ch);
}
inline void putstr(string s){
for(register int i=0;i<s.length();i++) putc(s[i]);
}
template<typename T>inline void put(const char ch,T x){
static std::streambuf *outbuf=cout.rdbuf();
static char stack[21];
static int top = 0;
if(x<0){
outbuf->sputc('-');
x=-x;
}
if(!x){
outbuf->sputc('0');
outbuf->sputc(ch);
return;
}
while(x){
stack[++top]=x%10+'0';
x/=10;
}
while(top){
outbuf->sputc(stack[top]);
--top;
}
outbuf->sputc(ch);
}
template<typename T,typename ...Args> inline void put(T a,Args ...args){
put(a);put(args...);
}
template<typename T,typename ...Args> inline void put(const char ch,T a,Args ...args){
put(ch,a);put(ch,args...);
}
}
using namespace IN;
using namespace OUT;
long long n,a[200005],flag,ans,t[200005],p[100005],top,b[200005];
#define max(x,y) (x>y?x:y)
inline long long C2(long long x){
return x*(x-1)/2;
}
inline long long C3(long long x){
if(x%3==1) return (x-1)/3*x/2%998244353*(x-2);
if(x%3==2) return (x-2)/3*(x-1)/2%998244353*x;
return x/3*(x-1)/2%998244353*(x-2);
}
int main(int argc, char const *argv[]){
std::ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
read(n);
for(int i=1;i<=n;i++) read(a[i]),t[a[i]]++;//t数组记录数的数量
/*
i:1 2 3 4 5 6
a:2 2 3 3 4 5
t:0 2 2 1 1 0
b:0 2 4 5 6 6
p:2 3
1 1 1 1 1
*/
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
if(t[a[i]]>=2) p[++top]=a[i],i+=t[a[i]]-1;
for(int i=1;i<=2e5;i++) b[i]=(b[i-1]+t[i])%998244353;//记录出来一段里面1~i有几个棍子
for(int i=1;i<=top;i++)
ans=(ans+(max(b[p[i]*2-1]-t[p[i]],0))%998244353*(t[p[i]]>2?C2(t[p[i]]):1)%998244353)%998244353+C3(t[p[i]])%998244353,ans%=998244353;//1~p[i]*2-1,分开计算等腰和等边
put('\n',ans%998244353);
return 0;
}