Problem p02893 (C++)

Buggy submission (status: Time Limit Exceeded):
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using u64 = uint_fast64_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
// constexpr long long MOD = 1000000007;
constexpr long long MOD = 998244353;
template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
inline int popcount(int x) { return __builtin_popcount(x); }
inline int popcount(long long x) { return __builtin_popcountll(x); }
void print() { cout << "\n"; }
template <class T, class... Args> void print(const T &x, const Args &...args) {
  cout << x << " ";
  print(args...);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

vector<long long> divisor(long long x) {
  assert(x);
  vector<long long> ret;
  for (long long i = 1; i * i <= x; i++) {
    if (x % i == 0) {
      ret.emplace_back(i);
      ret.emplace_back(x / i);
    }
  }
  sort(ret.begin(), ret.end());
  ret.erase(unique(begin(ret), end(ret)), end(ret));
  return ret;
}

template <uint_fast64_t Modulus> struct ModInt {
  using u64 = uint_fast64_t;

  u64 a;

  constexpr ModInt(const long long x = 0) noexcept
      : a(x >= 0 ? x % Modulus : (Modulus - (-x) % Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator^(const long long rhs) const noexcept {
    return ModInt(*this) ^= rhs;
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return a == rhs.a;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return a != rhs.a;
  }
  constexpr ModInt &operator+=(const ModInt rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp & 1)
        *this *= rhs;
      exp >>= 1;
      rhs *= rhs;
    }
    return *this;
  }
  constexpr ModInt &operator^=(long long exp) noexcept {
    ModInt rhs = a;
    a = 1;
    while (exp) {
      if (exp & 1)
        *this *= rhs;
      exp >>= 1;
      rhs *= rhs;
    }
    return *this;
  }

  friend ostream &operator<<(ostream &os, const ModInt &rhs) noexcept {
    return os << rhs.a;
  }
  friend istream &operator>>(istream &is, ModInt &rhs) noexcept {
    long long a;
    is >> a;
    rhs = a;
    return is;
  }
};

using mint = ModInt<MOD>;

template <typename S> vector<int> Z_Algorithm(const S &s) {
  // 先頭i文字目(0-indexed)から見て一致した文字数
  vector<int> prefix(s.size());

  prefix[0] = s.size();
  int i = 1, j = 0;
  while (i < s.size()) {
    while (i + j < s.size() && (s[j] == s[i + j]))
      ++j;
    prefix[i] = j;
    if (j == 0) {
      ++i;
      continue;
    }
    int k = 1;
    while (i + k < s.size() && k + prefix[k] < j)
      prefix[i + k] = prefix[k], ++k;
    i += k;
    j -= k;
  }

  return prefix;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin >> N;
  string S;
  cin >> S;

  auto A = divisor(N);
  vector<int> B;
  for (auto i : A) {
    if (i & 1)
      B.emplace_back(i);
  }
  reverse(all(B));
  int M = B.size();

  vector<mint> cnt(M);
  mint ans = 0;
  rep(i, M) {
    int n = N / B[i];
    string T = S;
    string I = S.substr(0, n);
    string R = "";
    rep(j, n) {
      if (I[j] == '0')
        R += '1';
      else
        R += '0';
    }

    mint val = 0;
    rep(j, n) {
      val *= 2;
      if (I[j] == '1')
        val += 1;
    }

    rep(j, N) {
      if (j & 1)
        T += R;
      else
        T += I;
    }
    auto Z = Z_Algorithm<string>(T);
    if (Z[N] == N)
      val += 1;
    else {
      if (S[Z[N]] == '1')
        val += 1;
    }
    cnt[i] += val;
    for (int j = i + 1; j < M; j++) {
      if (B[i] % B[j] == 0)
        cnt[j] -= cnt[i];
    }
    ans += cnt[i] * n * 2;
  }

  cout << ans << ln;
}


Fixed submission:
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using u64 = uint_fast64_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
// constexpr long long MOD = 1000000007;
constexpr long long MOD = 998244353;
template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
inline int popcount(int x) { return __builtin_popcount(x); }
inline int popcount(long long x) { return __builtin_popcountll(x); }
void print() { cout << "\n"; }
template <class T, class... Args> void print(const T &x, const Args &...args) {
  cout << x << " ";
  print(args...);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

vector<long long> divisor(long long x) {
  assert(x);
  vector<long long> ret;
  for (long long i = 1; i * i <= x; i++) {
    if (x % i == 0) {
      ret.emplace_back(i);
      ret.emplace_back(x / i);
    }
  }
  sort(ret.begin(), ret.end());
  ret.erase(unique(begin(ret), end(ret)), end(ret));
  return ret;
}

template <uint_fast64_t Modulus> struct ModInt {
  using u64 = uint_fast64_t;

  u64 a;

  constexpr ModInt(const long long x = 0) noexcept
      : a(x >= 0 ? x % Modulus : (Modulus - (-x) % Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator^(const long long rhs) const noexcept {
    return ModInt(*this) ^= rhs;
  }
  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return a == rhs.a;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return a != rhs.a;
  }
  constexpr ModInt &operator+=(const ModInt rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp & 1)
        *this *= rhs;
      exp >>= 1;
      rhs *= rhs;
    }
    return *this;
  }
  constexpr ModInt &operator^=(long long exp) noexcept {
    ModInt rhs = a;
    a = 1;
    while (exp) {
      if (exp & 1)
        *this *= rhs;
      exp >>= 1;
      rhs *= rhs;
    }
    return *this;
  }

  friend ostream &operator<<(ostream &os, const ModInt &rhs) noexcept {
    return os << rhs.a;
  }
  friend istream &operator>>(istream &is, ModInt &rhs) noexcept {
    long long a;
    is >> a;
    rhs = a;
    return is;
  }
};

using mint = ModInt<MOD>;

template <typename S> vector<int> Z_Algorithm(const S &s) {
  // 先頭i文字目(0-indexed)から見て一致した文字数
  vector<int> prefix(s.size());

  prefix[0] = s.size();
  int i = 1, j = 0;
  while (i < s.size()) {
    while (i + j < s.size() && (s[j] == s[i + j]))
      ++j;
    prefix[i] = j;
    if (j == 0) {
      ++i;
      continue;
    }
    int k = 1;
    while (i + k < s.size() && k + prefix[k] < j)
      prefix[i + k] = prefix[k], ++k;
    i += k;
    j -= k;
  }

  return prefix;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin >> N;
  string S;
  cin >> S;

  auto A = divisor(N);
  vector<int> B;
  for (auto i : A) {
    if (i & 1)
      B.emplace_back(i);
  }
  reverse(all(B));
  int M = B.size();

  vector<mint> cnt(M);
  mint ans = 0;
  rep(i, M) {
    int n = N / B[i];
    string T = S;
    string I = S.substr(0, n);
    string R = "";
    rep(j, n) {
      if (I[j] == '0')
        R += '1';
      else
        R += '0';
    }

    mint val = 0;
    rep(j, n) {
      val *= 2;
      if (I[j] == '1')
        val += 1;
    }

    rep(j, B[i]) {
      if (j & 1)
        T += R;
      else
        T += I;
    }
    auto Z = Z_Algorithm<string>(T);
    if (Z[N] == N)
      val += 1;
    else {
      if (S[Z[N]] == '1')
        val += 1;
    }
    cnt[i] += val;
    for (int j = i + 1; j < M; j++) {
      if (B[i] % B[j] == 0)
        cnt[j] -= cnt[i];
    }
    ans += cnt[i] * n * 2;
  }

  cout << ans << ln;
}