// g++-13 1.cpp -std=c++17 -O2 -I . #include using namespace std; #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include #include #include using namespace __gnu_pbds; #include #include #include #include using namespace atcoder; using ll = long long; using ld = long double; using vi = vector; using vvi = vector; using vll = vector; using vvll = vector; using vld = vector; using vvld = vector; using vst = vector; using vvst = vector; #define fi first #define se second #define pb push_back #define eb emplace_back #define pq_big(T) priority_queue,less> #define pq_small(T) priority_queue,greater> #define all(a) a.begin(),a.end() #define rep(i,start,end) for(ll i=start;i<(ll)(end);i++) #define per(i,start,end) for(ll i=start;i>=(ll)(end);i--) #define uniq(a) sort(all(a));a.erase(unique(all(a)),a.end()) random_device seed; mt19937_64 randint(seed()); ll grr(ll mi, ll ma) { // [mi, ma) return mi + randint() % (ma - mi); } // https://judge.yosupo.jp/submission/82871 // https://judge.yosupo.jp/submission/233535 #include template< typename S, S (*op)(S, S), S (*e)() > struct segmenttree{ private: int _n; std::vector node; public: segmenttree() = default; segmenttree(int n){ _n=1; while(_n &v){ int n=v.size(); _n=1; while(_n=0;i--){ node[i]=op(node[2*i],node[2*i+1]); } } // [i] <- val void set(int i,S val){ i+=_n; node[i]=val; while(i>1){ i>>=1; node[i]=op(node[2*i],node[2*i+1]); } } // [i] <- op([i],val) void update(int i,S val){ i+=_n; node[i]=op(node[i],val); while(i>1){ i>>=1; node[i]=op(node[2*i],node[2*i+1]); } } S get(int i){ i+=_n; return node[i]; } S prod(int l,int r){ S pdl=e(),pdr=e(); l+=_n;r+=_n; while(l>=1;r>>=1; } return op(pdl,pdr); }; }; using mint = modint998244353; mint op(mint a,mint b){ return a+b; } mint e(){ return 0; } int sq = 100; mint f(int m,int x,int y){ // ax > by かつ ax <= m なる (a, b) の個数 // sum_a(= 0 to m / x - 1) floor((a * x + x - 1) / y) // 2a > 3b かつ 2a <= 7 // 2-1/3 + 4-1/3 + 6-1/3 mint res=floor_sum(m/x,y,x,x-1); // mint nv=0; // rep(i,1,m+1){ // rep(j,1,m+1){ // if(i*x>j*y&&i*x<=m){ // nv++; // } // } // } // if(nv!=res){ // cout<>n>>m; vi d(n); rep(i,0,n)cin>>d[i]; segmenttree seg(m+1); vi cnt(sq+1,0); vector aft(sq+1,0); mint ans=0; vector> f_large_small(sq+1,vector(m+1)),f_small_large(sq+1,vector(m+1)); // f_large_small[i][j] := f(j,i) // f_small_large[i][j] := f(i,j) rep(i,1,sq+1){ rep(j,1,m+1){ f_large_small[i][j]=f(m,j,i); f_small_large[i][j]=f(m,i,j); } } auto ini=clock(); cerr<<(ld)(ini-st)/(CLOCKS_PER_SEC)<sq){ // large large mint ad=1; ad/=(m/d[i]); rep(j,1,m+1){ if(j*d[i]>m)break; ans+=seg.prod(j*d[i]+1,m+1)*ad; } // small large rep(j,1,sq+1){ ans+=cnt[j]*f_small_large[j][d[i]]; aft[j]+=f_large_small[j][d[i]]; } rep(j,1,m+1){ if(j*d[i]>m)break; seg.set(j*d[i],seg.get(j*d[i])+ad); } } else{ // large small // cout< "; ans+=aft[d[i]]; // cout<0)cout<