#include #include using namespace std; using namespace atcoder; using ll = long long; using mint = modint998244353; vector spf; map prime; void osa_k(ll n){ spf.resize(n+1); for (ll i=0; i<=n; i++) spf[i] = i; for (ll i=2; i*i<=n; i++){ if (spf[i] == i){ for (ll j=2; i*j <= n; j++){ spf[i*j] = min(spf[i*j], i); } } } } void prime_factor(ll n){ prime.clear(); while(n != 1){ prime[spf[n]]++; n /= spf[n]; } } int main(){ cin.tie(nullptr); ios_base::sync_with_stdio(false); /* dp(i)=末尾の要素がiとなるものの数 dp(A)+=1 dp(A)+=dp(k) (gcd(A, k)>1) sm(i)=dp(i*k)の総和 sm(2) = dp(2)+dp(4)+dp(6)+dp(8)+dp(10)+dp(12) sm(3) = dp(3)+dp(6)+dp(9)+dp(12) sm(6) = dp(6)+dp(12) dp(6) += sm(2)+sm(3)-sm(6) dp(8) += sm(2) dp(12) += sm(2)+sm(3)-sm(6) Aを素因数だけにしておく。(指数が2以上のものは意味がない。) dp(A)+= smの包除原理 sm(i)+=dp(A)-(前のdp(A)) (i|A) */ int N,M=1e6; osa_k(M); cin >> N; vector A(N); for (int i=0; i> A[i]; prime_factor(A[i]); int z=1; for (auto [x, y] : prime) z *= x; A[i] = z; } vector p(M+1); //素因数の数 vector> factors(M+1); for (int i=2; i<=M; i++){ int j=i; while(j!=1){ p[i]++; j /= spf[j]; } } for (int i=2; i<=M; i++){ for (int j=i; j<=M; j+=i) factors[j].push_back(i); } mint ans=0, prv=0, nxt=0; vector dp(M+1), sm(M+1); for (int i=0; i