#include #include using namespace std; using namespace atcoder; using ll = long long; using mint = modint998244353; vector spf; map prime; void osa_k(int n){ spf.resize(n+1); for (int i=0; i<=n; i++) spf[i] = i; for (int i=2; i*i<=n; i++){ if (spf[i] == i){ for (int j=2; i*j <= n; j++){ spf[i*j] = min(spf[i*j], i); } } } } void prime_factor(int n){ prime.clear(); while(n != 1){ prime[spf[n]]++; n /= spf[n]; } } //O(D(n)+log(n)) vector all_factor(int n){ vector res={1}; prime_factor(n); for (auto [p, e] : prime){ int x=1, m=res.size(); for (int j=0; j1) 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); //素因数の数 for (int i=2; i<=M; i++){ int j=i; while(j!=1){ p[i]++; j /= spf[j]; } } mint ans=0, prv=0, nxt=0; vector dp(M+1), sm(M+1); for (int i=0; i factors = all_factor(A[i]); for (auto x : factors) if (x > 1) dp[A[i]] += sm[x] * (p[x] % 2 == 0 ? -1 : 1); dp[A[i]]++; nxt = dp[A[i]]; for (auto x : factors) if (x > 1) sm[x] += nxt-prv; } for (int i=2; i<=M; i++) ans += dp[i]; cout << ans.val() << endl; return 0; }