Problem p02893 (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;
#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 + mod : a;
}
int Mul(int a, int b) { return (ll)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);
    mul(a, a);
    b >>= 1;
  }
  return ans;
}
const int N = 100005;
char a[N], A[N];
int n, b[N];
int flag[N], prime[N], cnt = 0, mu[N];
int f[N], g[N];
int calc(int x) {
  int tot = n / x;
  if (tot % 2 == 0)
    return 0;
  int ans = b[x];
  for (int i = 1; i <= x; ++i) {
    A[i] = a[i];
  }
  for (int i = x + 1; i <= n; ++i) {
    A[i] = '0' + '1' - A[i - x];
  }
  int flag = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i] < A[i]) {
      flag = -1;
      break;
    } else if (a[i] > A[i]) {
      flag = 1;
      break;
    }
  }
  if (flag >= 0)
    ++ans;
  return ans % mod;
}

void init() {
  read(n);
  scanf("%s", a + 1);
  for (int i = 1; i <= n; ++i) {
    b[i] = Mul(b[i - 1], 2);
    add(b[i], a[i] - '0');
  }
  mu[1] = 1;
  for (int i = 2; i <= n; ++i) {
    if (!flag[i]) {
      prime[++cnt] = i;
      mu[i] = mod - 1;
    }
    for (int j = 1; j <= cnt && i * prime[j] <= n; ++j) {
      flag[i * prime[j]] = 1;
      if (i % prime[j] == 0) {
        mu[i * prime[j]] = 0;
        break;
      }
      mu[i * prime[j]] = mod - mu[i];
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (n % i)
      continue;
    f[i] = calc(i);
  }
}

void solve() {
  for (int i = 1; i <= n; ++i) {
    for (int j = i; j <= n; j += i) {
      add(g[j], Mul(f[i], mu[j / i]));
    }
  }
  int ans = Mul(b[n] + 1, n + n);
  for (int i = 1; i <= n; ++i) {
    if (!f[i])
      continue;
    int tmp = Mul(n + n - i - i, g[i]);
    sub(ans, tmp);
  }
  printf("%d\n", ans);
}

#undef int
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;
#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 + mod : a;
}
int Mul(int a, int b) { return (ll)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);
    mul(a, a);
    b >>= 1;
  }
  return ans;
}
const int N = 400005;
char a[N], A[N];
int n, b[N];
int flag[N], prime[N], cnt = 0, mu[N];
int f[N], g[N];
int calc(int x) {
  int tot = n / x;
  if (tot % 2 == 0)
    return 0;
  int ans = b[x];
  for (int i = 1; i <= x; ++i) {
    A[i] = a[i];
  }
  for (int i = x + 1; i <= n; ++i) {
    A[i] = '0' + '1' - A[i - x];
  }
  int flag = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i] < A[i]) {
      flag = -1;
      break;
    } else if (a[i] > A[i]) {
      flag = 1;
      break;
    }
  }
  if (flag >= 0)
    ++ans;
  return ans % mod;
}

void init() {
  read(n);
  scanf("%s", a + 1);
  for (int i = 1; i <= n; ++i) {
    b[i] = Mul(b[i - 1], 2);
    add(b[i], a[i] - '0');
  }
  mu[1] = 1;
  for (int i = 2; i <= n; ++i) {
    if (!flag[i]) {
      prime[++cnt] = i;
      mu[i] = mod - 1;
    }
    for (int j = 1; j <= cnt && i * prime[j] <= n; ++j) {
      flag[i * prime[j]] = 1;
      if (i % prime[j] == 0) {
        mu[i * prime[j]] = 0;
        break;
      }
      mu[i * prime[j]] = mod - mu[i];
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (n % i)
      continue;
    f[i] = calc(i);
  }
}

void solve() {
  for (int i = 1; i <= n; ++i) {
    for (int j = i; j <= n; j += i) {
      add(g[j], Mul(f[i], mu[j / i]));
    }
  }
  int ans = Mul(b[n] + 1, n + n);
  for (int i = 1; i <= n; ++i) {
    if (!f[i])
      continue;
    int tmp = Mul(n + n - i - i, g[i]);
    sub(ans, tmp);
  }
  printf("%d\n", ans);
}

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