Problem p02893 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <unordered_map>
#include <vector>

using namespace std;

#define x first
#define y second
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define all(x) x.begin(), x.end()
#define SZ(x) int(x.size())
#define rep(i, a, b) for (int i = a; i < b; i++)
#define per(i, a, b) for (int i = b - 1; i >= a; i--)
#define DBG(x) cerr << (#x) << "=" << x << "\n";
#define ll long long
#define inf 1000000007
#define mod 998244353 // 1000000007
#define N 200005

template <typename U, typename V> void Min(U &a, const V &b) {
  if (a > b)
    a = b;
}
template <typename U, typename V> void Max(U &a, const V &b) {
  if (a < b)
    a = b;
}
template <typename U, typename V> void add(U &a, const V &b) {
  a = (a + b) % mod;
}
template <typename U> U gcd(U a, U b) {
  if (a == 0)
    return b;
  if (b == 0)
    return a;
  if (a >= b)
    return gcd(a % b, b);
  else
    return gcd(a, b % a);
}
int pow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = 1LL * ans * a % mod;
    a = 1LL * a * a % mod;
    b >>= 1;
  }
  return ans;
}

int go(int x, int n) {
  int z = x, m = (1 << n - 1);
  rep(i, 1, inf) {
    if (x & 1)
      x >>= 1;
    else {
      x = x / 2 + m;
    }
    if (x == z)
      return i;
    if (i > N)
      return -1;
  }
}
int h[N], q[N], p[N], d[N];
int cal(int i, int j) {
  return (h[i + j] - 1LL * h[i] * q[j] % mod + mod) % mod;
}
int cal1(int i, int j) {
  return (d[i + j] - 1LL * d[i] * q[j] % mod + mod) % mod;
}
char s[N];
int main() {
  int T, n, m, i, j, k, ca = 0, K;
  auto to = [&](int x, int n) {
    string s = "";
    rep(i, 0, n) {
      s.pb((x & 1) + '0');
      x >>= 1;
    }
    return s;
  };
  scanf("%d%s", &n, s);
  //{
  //    m = 0;
  //    ll w = 0;
  //    rep(i, 0, (1<<n)){
  //        K = go(i, n);
  //        w += K;
  //        //if(K != 2 * n)cerr << to(i, n) << " " << K << "\t";
  //        if(K != 2 * n)m++;
  //    }
  //    cerr << n << " " << m << " " << w % mod << "\n";
  //}
  vi v;
  rep(i, 3, n + 1) {
    if (n % i == 0) {
      v.pb(n / i * 2);
    }
    i++;
  }
  sort(all(v));
  q[0] = 1;
  p[0] = 1;
  rep(i, 0, n) {
    h[i + 1] = (h[i] * 29LL + s[i]) % mod;
    d[i + 1] = (d[i] * 29LL + (s[i] == '0' ? '1' : '0')) % mod;
    q[i + 1] = q[i] * 29LL % mod;
    p[i + 1] = p[i] * 2LL % mod;
  }
  ll ans = 0;
  vector<ll> w(SZ(v)), res(SZ(v), 0);
  rep(i, 0, n) {
    if (s[i] == '1') {
      h[i + 1] = (h[i] * 29LL + '0') % mod;
      d[i + 1] = (d[i] * 29LL + '1') % mod;
      rep(j, 0, SZ(v)) {
        w[j] = 0;
        if (v[j] / 2 >= i + 1) {
          w[j] = p[v[j] / 2 - i - 1];
          rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
          // cerr << i+1 << " " << v[j] << " " << w[j] << "\n";
          res[j] += w[j] % mod;
        } else if (v[j] >= i + 1) {
          k = i + 1 - v[j] / 2;
          // cerr << i+1 << " " << v[j] << "\n";
          if (cal(0, k) == cal1(v[j] / 2, k)) {
            w[j] = 1;
            rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
            res[j] += w[j];
          }
        } else if (cal(0, v[j] / 2) == cal1(v[j] / 2, v[j] / 2)) {
          k = (i + 1) / v[j] * v[j];
          int r = i + 1 - k;
          if (cal(0, k - v[j]) == cal(v[j], k - v[j]) &&
              cal(0, r) == cal(k, r)) {
            w[j] = 1;
            rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
            res[j] += w[k];
          }
        }
      }
      h[i + 1] = (h[i] * 29LL + '1') % mod;
      d[i + 1] = (d[i] * 29LL + '0') % mod;
    }
  }
  rep(j, 0, SZ(v)) if (cal(0, v[j] / 2) == cal1(v[j] / 2, v[j] / 2)) {
    k = n / v[j] * v[j];
    int r = n - k;
    if (cal(0, k - v[j]) == cal(v[j], k - v[j]) && cal(0, r) == cal(k, r)) {
      res[j]++;
      break;
    }
  }
  ll u = 0, sum = 0;
  rep(i, 0, n) u = (u * 2 + (s[i] - '0')) % mod;
  u++;
  rep(i, 0, SZ(v)) res[i] %= mod, sum += res[i], ans += res[i] * v[i] % mod;
  sum %= mod;
  u -= sum;
  if (u < 0)
    u += mod;
  // DBG(sum)DBG(SZ(v))
  ans += 2LL * n * u % mod;
  ans %= mod;
  if (ans < 0)
    ans += mod;
  printf("%lld\n", ans);
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <unordered_map>
#include <vector>

using namespace std;

#define x first
#define y second
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define all(x) x.begin(), x.end()
#define SZ(x) int(x.size())
#define rep(i, a, b) for (int i = a; i < b; i++)
#define per(i, a, b) for (int i = b - 1; i >= a; i--)
#define DBG(x) cerr << (#x) << "=" << x << "\n";
#define ll long long
#define inf 1000000007
#define mod 998244353 // 1000000007
#define N 200005

template <typename U, typename V> void Min(U &a, const V &b) {
  if (a > b)
    a = b;
}
template <typename U, typename V> void Max(U &a, const V &b) {
  if (a < b)
    a = b;
}
template <typename U, typename V> void add(U &a, const V &b) {
  a = (a + b) % mod;
}
template <typename U> U gcd(U a, U b) {
  if (a == 0)
    return b;
  if (b == 0)
    return a;
  if (a >= b)
    return gcd(a % b, b);
  else
    return gcd(a, b % a);
}
int pow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = 1LL * ans * a % mod;
    a = 1LL * a * a % mod;
    b >>= 1;
  }
  return ans;
}

int go(int x, int n) {
  int z = x, m = (1 << n - 1);
  rep(i, 1, inf) {
    if (x & 1)
      x >>= 1;
    else {
      x = x / 2 + m;
    }
    if (x == z)
      return i;
    if (i > N)
      return -1;
  }
}
int h[N], q[N], p[N], d[N];
int cal(int i, int j) {
  return (h[i + j] - 1LL * h[i] * q[j] % mod + mod) % mod;
}
int cal1(int i, int j) {
  return (d[i + j] - 1LL * d[i] * q[j] % mod + mod) % mod;
}
char s[N];
int main() {
  int T, n, m, i, j, k, ca = 0, K;
  auto to = [&](int x, int n) {
    string s = "";
    rep(i, 0, n) {
      s.pb((x & 1) + '0');
      x >>= 1;
    }
    return s;
  };
  scanf("%d%s", &n, s);
  //{
  //    m = 0;
  //    ll w = 0;
  //    rep(i, 0, (1<<n)){
  //        K = go(i, n);
  //        w += K;
  //        //if(K != 2 * n)cerr << to(i, n) << " " << K << "\t";
  //        if(K != 2 * n)m++;
  //    }
  //    cerr << n << " " << m << " " << w % mod << "\n";
  //}
  vi v;
  rep(i, 3, n + 1) {
    if (n % i == 0) {
      v.pb(n / i * 2);
    }
    i++;
  }
  sort(all(v));
  q[0] = 1;
  p[0] = 1;
  rep(i, 0, n) {
    h[i + 1] = (h[i] * 29LL + s[i]) % mod;
    d[i + 1] = (d[i] * 29LL + (s[i] == '0' ? '1' : '0')) % mod;
    q[i + 1] = q[i] * 29LL % mod;
    p[i + 1] = p[i] * 2LL % mod;
  }
  ll ans = 0;
  vector<ll> w(SZ(v)), res(SZ(v), 0);
  rep(i, 0, n) {
    if (s[i] == '1') {
      h[i + 1] = (h[i] * 29LL + '0') % mod;
      d[i + 1] = (d[i] * 29LL + '1') % mod;
      rep(j, 0, SZ(v)) {
        w[j] = 0;
        if (v[j] / 2 >= i + 1) {
          w[j] = p[v[j] / 2 - i - 1];
          rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
          // cerr << i+1 << " " << v[j] << " " << w[j] << "\n";
          res[j] += w[j] % mod;
        } else if (v[j] >= i + 1) {
          k = i + 1 - v[j] / 2;
          // cerr << i+1 << " " << v[j] << "\n";
          if (cal(0, k) == cal1(v[j] / 2, k)) {
            w[j] = 1;
            rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
            res[j] += w[j];
          }
        } else if (cal(0, v[j] / 2) == cal1(v[j] / 2, v[j] / 2)) {
          k = (i + 1) / v[j] * v[j];
          int r = i + 1 - k;
          if (cal(0, k - v[j]) == cal(v[j], k - v[j]) &&
              cal(0, r) == cal(k, r)) {
            w[j] = 1;
            rep(k, 0, j) if (v[j] % v[k] == 0) w[j] -= w[k];
            res[j] += w[j];
          }
        }
      }
      h[i + 1] = (h[i] * 29LL + '1') % mod;
      d[i + 1] = (d[i] * 29LL + '0') % mod;
    }
  }
  rep(j, 0, SZ(v)) if (cal(0, v[j] / 2) == cal1(v[j] / 2, v[j] / 2)) {
    k = n / v[j] * v[j];
    int r = n - k;
    if (cal(0, k - v[j]) == cal(v[j], k - v[j]) && cal(0, r) == cal(k, r)) {
      res[j]++;
      break;
    }
  }
  ll u = 0, sum = 0;
  rep(i, 0, n) u = (u * 2 + (s[i] - '0')) % mod;
  u++;
  rep(i, 0, SZ(v)) res[i] %= mod, sum += res[i], ans += res[i] * v[i] % mod;
  sum %= mod;
  u -= sum;
  if (u < 0)
    u += mod;
  // DBG(sum)DBG(SZ(v))
  ans += 2LL * n * u % mod;
  ans %= mod;
  if (ans < 0)
    ans += mod;
  printf("%lld\n", ans);
}