Problem p02905 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define m_p make_pair
#define sz(x) (int)x.size()
#define out(x) cerr << #x << " = " << x << " "
#define outln(x) cerr << #x << " = " << x << endl
#define outarr(x, l, r)                                                        \
  cerr << #x "[" << l << "-" << r << "] = ";                                   \
  for (int _i = l; _i <= r; ++_i)                                              \
    cerr << x[_i] << " ";                                                      \
  cerr << endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
#define gc() getchar()
// char buf[1<<23],*p1=buf,*p2=buf;
// #define gc()
// (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <class T> void read(T &x) {
  x = 0;
  char c = gc();
  int flag = 0;
  while (c < '0' || c > '9')
    flag |= (c == '-'), c = gc();
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
  if (flag)
    x = -x;
}
template <class T> T _max(T a, T b) { return a > b ? a : b; }
template <class T> T _min(T a, T b) { return a < b ? a : b; }
template <class T> bool checkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
template <class T> bool checkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
const int mod = 998244353;
int Add(int a, int b) {
  a += b;
  return a >= mod ? a - mod : a;
}
int Sub(int a, int b) {
  a -= b;
  return a >= 0 ? a : a + mod;
}
int Mul(int a, int b) { return 1LL * a * b % mod; }
void add(int &a, int b) { a = Add(a, b); }
void sub(int &a, int b) { a = Sub(a, b); }
void mul(int &a, int b) { a = Mul(a, b); }
int qpow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      mul(ans, a);
    a = Mul(a, a);
    b >>= 1;
  }
  return ans;
}

const int N = 200005, M = 1000000;
int n, k, cnt[N], mx = 0;
int prime[M + 5], flag[M + 5], inv[M + 5], mu[M + 5], f[M + 5], g[M + 5];
void init() {
  read(n);
  for (int i = 1, x; i <= n; ++i) {
    read(x);
    add(cnt[x], x);
    checkmax(mx, x);
  }
  int tot = 0;
  mu[1] = 1;
  for (int i = 2; i <= mx; ++i) {
    if (!flag[i]) {
      prime[++tot] = i;
      mu[i] = mod - 1;
    }
    for (int j = 1; j <= tot && i * prime[j] <= mx; ++j) {
      flag[i * prime[j]] = 1;
      if (i % prime[j] == 0) {
        mu[i * prime[j]] = 0;
        break;
      }
      mu[i * prime[j]] = mod - mu[i];
    }
  }
  inv[1] = 1;
  for (int i = 2; i <= mx; ++i) {
    inv[i] = Mul(inv[mod % i], mod - mod / i);
  }
  for (int i = 1; i <= mx; ++i) {
    for (int j = i; j <= mx; j += i) {
      add(f[i], cnt[j]);
      add(g[j], Mul(inv[i], mu[j / i]));
    }
  }
}

void solve() {
  int ans = 0;
  for (int i = 1; i <= mx; ++i) {
    add(ans, Mul(Mul(f[i], f[i]), g[i]));
  }
  sub(ans, f[1]);
  mul(ans, inv[2]);
  printf("%d\n", ans);
}

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


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define m_p make_pair
#define sz(x) (int)x.size()
#define out(x) cerr << #x << " = " << x << " "
#define outln(x) cerr << #x << " = " << x << endl
#define outarr(x, l, r)                                                        \
  cerr << #x "[" << l << "-" << r << "] = ";                                   \
  for (int _i = l; _i <= r; ++_i)                                              \
    cerr << x[_i] << " ";                                                      \
  cerr << endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
#define gc() getchar()
// char buf[1<<23],*p1=buf,*p2=buf;
// #define gc()
// (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <class T> void read(T &x) {
  x = 0;
  char c = gc();
  int flag = 0;
  while (c < '0' || c > '9')
    flag |= (c == '-'), c = gc();
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
  if (flag)
    x = -x;
}
template <class T> T _max(T a, T b) { return a > b ? a : b; }
template <class T> T _min(T a, T b) { return a < b ? a : b; }
template <class T> bool checkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
template <class T> bool checkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
const int mod = 998244353;
int Add(int a, int b) {
  a += b;
  return a >= mod ? a - mod : a;
}
int Sub(int a, int b) {
  a -= b;
  return a >= 0 ? a : a + mod;
}
int Mul(int a, int b) { return 1LL * a * b % mod; }
void add(int &a, int b) { a = Add(a, b); }
void sub(int &a, int b) { a = Sub(a, b); }
void mul(int &a, int b) { a = Mul(a, b); }
int qpow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      mul(ans, a);
    a = Mul(a, a);
    b >>= 1;
  }
  return ans;
}

const int N = 200005, M = 1000000;
int n, k, cnt[M + 5], mx = 0;
int prime[M + 5], flag[M + 5], inv[M + 5], mu[M + 5], f[M + 5], g[M + 5];
void init() {
  read(n);
  for (int i = 1, x; i <= n; ++i) {
    read(x);
    add(cnt[x], x);
    checkmax(mx, x);
  }
  int tot = 0;
  mu[1] = 1;
  for (int i = 2; i <= mx; ++i) {
    if (!flag[i]) {
      prime[++tot] = i;
      mu[i] = mod - 1;
    }
    for (int j = 1; j <= tot && i * prime[j] <= mx; ++j) {
      flag[i * prime[j]] = 1;
      if (i % prime[j] == 0) {
        mu[i * prime[j]] = 0;
        break;
      }
      mu[i * prime[j]] = mod - mu[i];
    }
  }
  inv[1] = 1;
  for (int i = 2; i <= mx; ++i) {
    inv[i] = Mul(inv[mod % i], mod - mod / i);
  }
  for (int i = 1; i <= mx; ++i) {
    for (int j = i; j <= mx; j += i) {
      add(f[i], cnt[j]);
      add(g[j], Mul(inv[i], mu[j / i]));
    }
  }
}

void solve() {
  int ans = 0;
  for (int i = 1; i <= mx; ++i) {
    add(ans, Mul(Mul(f[i], f[i]), g[i]));
  }
  sub(ans, f[1]);
  mul(ans, inv[2]);
  printf("%d\n", ans);
}

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