Problem p02905 (C++)

Buggy submission (status: Time Limit Exceeded):
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using dd = double;
using vdd = std::vector<dd>;
using vvdd = std::vector<vdd>;
using vvvdd = std::vector<vvdd>;

constexpr ll INF = 1LL << 60;
constexpr dd EPS = 1e-11;

// cin,cout高速化のおまじない＋桁数指定
struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;

#define REPS(i, S, E) for (ll i = (S); i <= (E); i++)
#define REP(i, N) REPS(i, 0, N - 1)
#define DEPS(i, S, E) for (ll i = (E); i >= (S); i--)
#define DEP(i, N) DEPS(i, 0, N - 1)
#define EACH(e, v) for (auto &&e : v)

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline T MaxE(vector<T> &v, ll S, ll E) {
  T m = v[S];
  REPS(i, S, E) chmax(m, v[i]);
  return m;
} // v[S]～v[E]の最大値
template <class T> inline T MinE(vector<T> &v, ll S, ll E) {
  T m = v[S];
  REPS(i, S, E) chmin(m, v[i]);
  return m;
} // v[S]～v[E]の最小値
template <class T> inline T MaxE(vector<T> &v, ll N) {
  return MaxE(v, 0, N - 1);
} // 先頭N個中の最大値
template <class T> inline T MinE(vector<T> &v, ll N) {
  return MinE(v, 0, N - 1);
}
template <class T> inline T MaxE(vector<T> &v) { return MaxE(v, (ll)v.size()); }
template <class T> inline T MinE(vector<T> &v) { return MinE(v, (ll)v.size()); }
template <class T> inline ll MaxI(vector<T> &v, ll S, ll E) {
  ll m = S;
  REPS(i, S, E) {
    if (v[i] > v[m])
      m = i;
  }
  return m;
}
template <class T> inline ll MinI(vector<T> &v, ll S, ll E) {
  ll m = S;
  REPS(i, S, E) {
    if (v[i] < v[m])
      m = i;
  }
  return m;
}
template <class T> inline ll MaxI(vector<T> &v, ll N) {
  return MaxI(v, 0, N - 1);
}
template <class T> inline ll MinI(vector<T> &v, ll N) {
  return MinI(v, 0, N - 1);
}
template <class T> inline ll MaxI(vector<T> &v) {
  return MaxI(v, (ll)v.size());
}
template <class T> inline ll MinI(vector<T> &v) {
  return MinI(v, (ll)v.size());
}
template <class T> inline T Sum(vector<T> &v, ll S, ll E) {
  T s = v[S];
  REPS(i, S + 1, E) s += v[i];
  return s;
}
template <class T> inline T Sum(vector<T> &v, ll N) { return Sum(v, 0, N - 1); }
template <class T> inline T Sum(vector<T> &v) { return Sum(v, v.size()); }
template <class T> inline T POW(T a, ll n) {
  T r = 1;
  for (; n > 0; n >>= 1, a *= a) {
    if (n & 1)
      r *= a;
  }
  return r;
}
inline ll POW(int a, ll n) { return POW((ll)a, n); }
inline ll MSB(ll a) {
  for (ll o = 63, x = -1;;) {
    ll m = (o + x) / 2;
    if (a < (1LL << m))
      o = m;
    else
      x = m;
    if (o - x == 1)
      return x;
  }
}
inline ll CEIL(ll a, ll b) { return (a + b - 1) / b; }

template <class T = ll> inline vector<T> cinv(ll N) {
  vector<T> v(N);
  REP(i, N) cin >> v[i];
  return move(v);
}
template <class T = ll, class S = ll> inline vector<pair<T, S>> cinv2(ll N) {
  vector<pair<T, S>> v(N);
  REP(i, N) { cin >> v[i].first >> v[i].second; }
  return move(v);
}
template <class T = ll, class S = ll, class R = ll>
inline vector<tuple<T, S, R>> cinv3(ll N) {
  vector<tuple<T, S, R>> v(N);
  REP(i, N) { cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]); }
  return move(v);
}
template <class T = ll, class S = ll, class R = ll, class Q = ll>
inline vector<tuple<T, S, R, Q>> cinv4(ll N) {
  vector<tuple<T, S, R, Q>> v(N);
  REP(i, N) {
    cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]) >> get<3>(v[i]);
  }
  return move(v);
}
template <class T> inline void coutv(vector<T> &v, char deli = ' ') {
  ll N = (ll)v.size();
  REP(i, N) { cout << v[i] << ((i == N - 1) ? '\n' : deli); }
}
template <class T> void bye(T a) {
  cout << a << '\n';
  exit(0);
}

struct mll {
  static ll MOD;
  ll val;
  mll(ll v = 0) : val(v % MOD) {
    if (val < 0)
      val += MOD;
  }
  mll operator-() const { return -val; }
  mll operator+(const mll &b) const { return val + b.val; }
  mll operator-(const mll &b) const { return val - b.val; }
  mll operator*(const mll &b) const { return val * b.val; }
  mll operator/(const mll &b) const { return mll(*this) /= b; }
  mll operator+(ll b) const { return *this + mll(b); }
  mll operator-(ll b) const { return *this - mll(b); }
  mll operator*(ll b) const { return *this * mll(b); }
  friend mll operator+(ll a, const mll &b) { return b + a; }
  friend mll operator-(ll a, const mll &b) { return -b + a; }
  friend mll operator*(ll a, const mll &b) { return b * a; }
  mll &operator+=(const mll &b) {
    val = (val + b.val) % MOD;
    return *this;
  }
  mll &operator-=(const mll &b) {
    val = (val + MOD - b.val) % MOD;
    return *this;
  }
  mll &operator*=(const mll &b) {
    val = (val * b.val) % MOD;
    return *this;
  }
  mll &operator/=(const mll &b) {
    ll c = b.val, d = MOD, u = 1, v = 0;
    while (d) {
      ll t = c / d;
      c -= t * d;
      swap(c, d);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0)
      val += MOD;
    return *this;
  }
  mll &operator+=(ll b) { return *this += mll(b); }
  mll &operator-=(ll b) { return *this -= mll(b); }
  mll &operator*=(ll b) { return *this *= mll(b); }
  mll &operator/=(ll b) { return *this /= mll(b); }
  bool operator==(const mll &b) { return val == b.val; }
  bool operator!=(const mll &b) { return val != b.val; }
  bool operator==(ll b) { return *this == mll(b); }
  bool operator!=(ll b) { return *this != mll(b); }
  friend bool operator==(ll a, const mll &b) { return mll(a) == b.val; }
  friend bool operator!=(ll a, const mll &b) { return mll(a) != b.val; }
  friend ostream &operator<<(ostream &os, const mll &a) { return os << a.val; }
  friend istream &operator>>(istream &is, mll &a) { return is >> a.val; }
  static mll Combination(ll a, ll b) {
    chmin(b, a - b);
    if (b < 0)
      return mll(0);
    mll c = 1;
    REP(i, b) c *= a - i;
    REP(i, b) c /= i + 1;
    return c;
  }
};
ll mll::MOD = 998244353LL; // 998244353LL;//(ll)(1e9 + 7);
using vmll = std::vector<mll>;
using vvmll = std::vector<vmll>;
using vvvmll = std::vector<vvmll>;
using vvvvmll = std::vector<vvvmll>;

ll M = 1000000;

void solve() {
  ll N;
  cin >> N;
  vll A = cinv(N);

  // 予め1～100万の約数を求めておく
  vvll ykVec(M + 1);
  EACH(v, ykVec) v.reserve(24);

  REPS(i, 1, M) {
    REPS(k, 1, M) {
      if (i * k > M)
        break;
      ykVec[i * k].push_back(i);
    }
  }

  vmll sum(M + 1, 0);  // sum[i] iの倍数のみの和
  vmll sum2(M + 1, 0); // sum2[i] iの倍数のみの2乗和

  EACH(a, A) {
    EACH(yk, ykVec[a]) {
      sum[yk] += a;
      sum2[yk] += (a * a);
    }
  }

  vmll sekiSum(M + 1);
  REPS(i, 1, M) { sekiSum[i] = sum[i] * sum[i] - sum2[i]; }

  vmll lcmSum(M + 1, 0); // lcmSum[i] gcdがiの組のlcmの和
  DEPS(i, 1, M) {
    lcmSum[i] = sekiSum[i];
    REPS(k, 2, M) {
      if (i * k > M)
        break;
      lcmSum[i] -= lcmSum[i * k];
    }
  }
  REPS(i, 1, M) lcmSum[i] /= i;

  mll ans = Sum(lcmSum, 1, M);
  cout << ans / 2 << '\n';
}

int main() {
  solve();
  return 0;
}


Fixed submission:
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using dd = double;
using vdd = std::vector<dd>;
using vvdd = std::vector<vdd>;
using vvvdd = std::vector<vvdd>;

constexpr ll INF = 1LL << 60;
constexpr dd EPS = 1e-11;

// cin,cout高速化のおまじない＋桁数指定
struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;

#define REPS(i, S, E) for (ll i = (S); i <= (E); i++)
#define REP(i, N) REPS(i, 0, N - 1)
#define DEPS(i, S, E) for (ll i = (E); i >= (S); i--)
#define DEP(i, N) DEPS(i, 0, N - 1)
#define EACH(e, v) for (auto &&e : v)

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline T MaxE(vector<T> &v, ll S, ll E) {
  T m = v[S];
  REPS(i, S, E) chmax(m, v[i]);
  return m;
} // v[S]～v[E]の最大値
template <class T> inline T MinE(vector<T> &v, ll S, ll E) {
  T m = v[S];
  REPS(i, S, E) chmin(m, v[i]);
  return m;
} // v[S]～v[E]の最小値
template <class T> inline T MaxE(vector<T> &v, ll N) {
  return MaxE(v, 0, N - 1);
} // 先頭N個中の最大値
template <class T> inline T MinE(vector<T> &v, ll N) {
  return MinE(v, 0, N - 1);
}
template <class T> inline T MaxE(vector<T> &v) { return MaxE(v, (ll)v.size()); }
template <class T> inline T MinE(vector<T> &v) { return MinE(v, (ll)v.size()); }
template <class T> inline ll MaxI(vector<T> &v, ll S, ll E) {
  ll m = S;
  REPS(i, S, E) {
    if (v[i] > v[m])
      m = i;
  }
  return m;
}
template <class T> inline ll MinI(vector<T> &v, ll S, ll E) {
  ll m = S;
  REPS(i, S, E) {
    if (v[i] < v[m])
      m = i;
  }
  return m;
}
template <class T> inline ll MaxI(vector<T> &v, ll N) {
  return MaxI(v, 0, N - 1);
}
template <class T> inline ll MinI(vector<T> &v, ll N) {
  return MinI(v, 0, N - 1);
}
template <class T> inline ll MaxI(vector<T> &v) {
  return MaxI(v, (ll)v.size());
}
template <class T> inline ll MinI(vector<T> &v) {
  return MinI(v, (ll)v.size());
}
template <class T> inline T Sum(vector<T> &v, ll S, ll E) {
  T s = v[S];
  REPS(i, S + 1, E) s += v[i];
  return s;
}
template <class T> inline T Sum(vector<T> &v, ll N) { return Sum(v, 0, N - 1); }
template <class T> inline T Sum(vector<T> &v) { return Sum(v, v.size()); }
template <class T> inline T POW(T a, ll n) {
  T r = 1;
  for (; n > 0; n >>= 1, a *= a) {
    if (n & 1)
      r *= a;
  }
  return r;
}
inline ll POW(int a, ll n) { return POW((ll)a, n); }
inline ll MSB(ll a) {
  for (ll o = 63, x = -1;;) {
    ll m = (o + x) / 2;
    if (a < (1LL << m))
      o = m;
    else
      x = m;
    if (o - x == 1)
      return x;
  }
}
inline ll CEIL(ll a, ll b) { return (a + b - 1) / b; }

template <class T = ll> inline vector<T> cinv(ll N) {
  vector<T> v(N);
  REP(i, N) cin >> v[i];
  return move(v);
}
template <class T = ll, class S = ll> inline vector<pair<T, S>> cinv2(ll N) {
  vector<pair<T, S>> v(N);
  REP(i, N) { cin >> v[i].first >> v[i].second; }
  return move(v);
}
template <class T = ll, class S = ll, class R = ll>
inline vector<tuple<T, S, R>> cinv3(ll N) {
  vector<tuple<T, S, R>> v(N);
  REP(i, N) { cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]); }
  return move(v);
}
template <class T = ll, class S = ll, class R = ll, class Q = ll>
inline vector<tuple<T, S, R, Q>> cinv4(ll N) {
  vector<tuple<T, S, R, Q>> v(N);
  REP(i, N) {
    cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]) >> get<3>(v[i]);
  }
  return move(v);
}
template <class T> inline void coutv(vector<T> &v, char deli = ' ') {
  ll N = (ll)v.size();
  REP(i, N) { cout << v[i] << ((i == N - 1) ? '\n' : deli); }
}
template <class T> void bye(T a) {
  cout << a << '\n';
  exit(0);
}

struct mll {
  static ll MOD;
  ll val;
  mll(ll v = 0) : val(v % MOD) {
    if (val < 0)
      val += MOD;
  }
  mll operator-() const { return -val; }
  mll operator+(const mll &b) const { return val + b.val; }
  mll operator-(const mll &b) const { return val - b.val; }
  mll operator*(const mll &b) const { return val * b.val; }
  mll operator/(const mll &b) const { return mll(*this) /= b; }
  mll operator+(ll b) const { return *this + mll(b); }
  mll operator-(ll b) const { return *this - mll(b); }
  mll operator*(ll b) const { return *this * mll(b); }
  friend mll operator+(ll a, const mll &b) { return b + a; }
  friend mll operator-(ll a, const mll &b) { return -b + a; }
  friend mll operator*(ll a, const mll &b) { return b * a; }
  mll &operator+=(const mll &b) {
    val = (val + b.val) % MOD;
    return *this;
  }
  mll &operator-=(const mll &b) {
    val = (val + MOD - b.val) % MOD;
    return *this;
  }
  mll &operator*=(const mll &b) {
    val = (val * b.val) % MOD;
    return *this;
  }
  mll &operator/=(const mll &b) {
    ll c = b.val, d = MOD, u = 1, v = 0;
    while (d) {
      ll t = c / d;
      c -= t * d;
      swap(c, d);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0)
      val += MOD;
    return *this;
  }
  mll &operator+=(ll b) { return *this += mll(b); }
  mll &operator-=(ll b) { return *this -= mll(b); }
  mll &operator*=(ll b) { return *this *= mll(b); }
  mll &operator/=(ll b) { return *this /= mll(b); }
  bool operator==(const mll &b) { return val == b.val; }
  bool operator!=(const mll &b) { return val != b.val; }
  bool operator==(ll b) { return *this == mll(b); }
  bool operator!=(ll b) { return *this != mll(b); }
  friend bool operator==(ll a, const mll &b) { return mll(a) == b.val; }
  friend bool operator!=(ll a, const mll &b) { return mll(a) != b.val; }
  friend ostream &operator<<(ostream &os, const mll &a) { return os << a.val; }
  friend istream &operator>>(istream &is, mll &a) { return is >> a.val; }
  static mll Combination(ll a, ll b) {
    chmin(b, a - b);
    if (b < 0)
      return mll(0);
    mll c = 1;
    REP(i, b) c *= a - i;
    REP(i, b) c /= i + 1;
    return c;
  }
};
ll mll::MOD = 998244353LL; // 998244353LL;//(ll)(1e9 + 7);
using vmll = std::vector<mll>;
using vvmll = std::vector<vmll>;
using vvvmll = std::vector<vvmll>;
using vvvvmll = std::vector<vvvmll>;

ll M = 1000000;

void solve() {
  ll N;
  cin >> N;
  vll A = cinv(N);

  // 予め1～100万の約数を求めておく
  vvll ykVec(M + 1);
  EACH(v, ykVec) v.reserve(24);

  REPS(i, 1, M) {
    REPS(k, 1, M) {
      if (i * k > M)
        break;
      ykVec[i * k].push_back(i);
    }
  }

  vmll sum(M + 1, 0);  // sum[i] iの倍数のみの和
  vmll sum2(M + 1, 0); // sum2[i] iの倍数のみの2乗和

  EACH(a, A) {
    EACH(yk, ykVec[a]) {
      sum[yk] += a;
      sum2[yk] += (a * a);
    }
  }

  vmll sekiSum(M + 1);
  REPS(i, 1, M) { sekiSum[i] = sum[i] * sum[i] - sum2[i]; }

  vmll lcmSum(M + 1, 0); // lcmSum[i] gcdがiの組のlcmの和
  DEPS(i, 1, M) {
    lcmSum[i] = sekiSum[i];
    REPS(k, 2, M) {
      if (i * k > M)
        break;
      lcmSum[i] -= lcmSum[i * k];
    }
  }
  REPS(i, 1, M) {
    if (lcmSum[i] != 0)
      lcmSum[i] /= i;
  }
  mll ans = Sum(lcmSum, 1, M);
  cout << ans / 2 << '\n';
}

int main() {
  solve();
  return 0;
}