Problem p02893 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

int N, dp[200009], bit[200009], p2[200009], v[200009];
char initSir[200009];
const int mod = 998244353;

int add(int x, int y) {
  int ans = x + y;
  if (ans >= mod)
    ans -= mod;
  return ans;
}
int subtract(int x, int y) {
  if (x >= y)
    return x - y;
  return x - y + mod;
}
int mul(int x, int y) { return 1LL * x * y % mod; }
void adto(int &x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
}

int power(int a, int b) {
  int p = 1;
  for (int i = 0; (1 << i) <= b; i++) {
    if (b & (1 << i))
      p = mul(p, a);
    a = mul(a, a);
  }
  return p;
}

int fac[2000009], inv[2000009];
void Prec(int lim) {
  fac[0] = inv[0] = 1;
  for (int i = 1; i <= lim; i++)
    fac[i] = mul(fac[i - 1], i);
  inv[lim] = power(fac[lim], mod - 2);
  for (int i = lim - 1; i >= 0; i--)
    inv[i] = mul(inv[i + 1], i + 1);
}
int comb(int N, int K) {
  if (K > N || N < 0 || K < 0)
    return 0;
  int ans = mul(fac[N], inv[N - K]);
  ans = mul(ans, inv[K]);
  return ans;
}

int gcd(int a, int b) {
  int r;
  while (b)
    r = a % b, a = b, b = r;
  return a;
}

bool isBig = 0;
int getCount(int P) {
  int D = gcd(P, N); /// number of cycles
  if ((P / D) % 2 == 1)
    return 0;
  if (isBig)
    return p2[D];
  int ans = 0;
  for (int i = N - 1; i >= N - D; i--)
    if (bit[i])
      adto(ans, p2[D - (N - i)]);
  for (int i = N - 1; i >= N - D; i--) {
    v[i] = bit[i];
    for (int step = 1, j = i; step < N / D; step++, j = (j + P) % N)
      v[(j + P) % N] = v[j] ^ (j + P >= N);
  }
  int i = N - 1;
  while (i >= 0 && v[i] == bit[i])
    i--;
  if (i >= 0 && bit[i] == 1)
    adto(ans, 1);
  return ans;
}

void add1() {
  int i = 0;
  while (bit[i] == 1)
    bit[i] = 0, i++;
  bit[i] = 1;
  isBig = (i == N);
}

int main() {
  // freopen ("input", "r", stdin);
  // freopen ("output", "w", stdout);

  scanf("%d\n%s", &N, initSir);
  for (int i = 0; i < N; i++)
    bit[i] = initSir[N - 1 - i] - '0';
  add1();
  p2[0] = 1;
  for (int i = 1; i <= N; i++)
    p2[i] = add(p2[i - 1], p2[i - 1]);
  int ans = 0;
  for (int i = 0; i <= N; i++)
    if (bit[i])
      adto(dp[2 * N],
           p2[i]); /// all dp is referring to numbers strictly smaller than X
  for (int i = 1; i < 2 * N; i++)
    if ((2 * N) % i == 0) {
      // printf ("%d: %d\n", i, getCount (i));
      adto(dp[i], getCount(i));
      for (int j = i + i; j <= 2 * N; j += i)
        dp[j] = subtract(dp[j], dp[i]);
    }
  for (int i = 1; i <= 2 * N; i++)
    if ((2 * N) % i == 0)
      adto(ans, mul(dp[i], i));
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

int N, dp[400009], bit[200009], p2[200009], v[200009];
char initSir[200009];
const int mod = 998244353;

int add(int x, int y) {
  int ans = x + y;
  if (ans >= mod)
    ans -= mod;
  return ans;
}
int subtract(int x, int y) {
  if (x >= y)
    return x - y;
  return x - y + mod;
}
int mul(int x, int y) { return 1LL * x * y % mod; }
void adto(int &x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
}

int power(int a, int b) {
  int p = 1;
  for (int i = 0; (1 << i) <= b; i++) {
    if (b & (1 << i))
      p = mul(p, a);
    a = mul(a, a);
  }
  return p;
}

int fac[2000009], inv[2000009];
void Prec(int lim) {
  fac[0] = inv[0] = 1;
  for (int i = 1; i <= lim; i++)
    fac[i] = mul(fac[i - 1], i);
  inv[lim] = power(fac[lim], mod - 2);
  for (int i = lim - 1; i >= 0; i--)
    inv[i] = mul(inv[i + 1], i + 1);
}
int comb(int N, int K) {
  if (K > N || N < 0 || K < 0)
    return 0;
  int ans = mul(fac[N], inv[N - K]);
  ans = mul(ans, inv[K]);
  return ans;
}

int gcd(int a, int b) {
  int r;
  while (b)
    r = a % b, a = b, b = r;
  return a;
}

bool isBig = 0;
int getCount(int P) {
  int D = gcd(P, N); /// number of cycles
  if ((P / D) % 2 == 1)
    return 0;
  if (isBig)
    return p2[D];
  int ans = 0;
  for (int i = N - 1; i >= N - D; i--)
    if (bit[i])
      adto(ans, p2[D - (N - i)]);
  for (int i = N - 1; i >= N - D; i--) {
    v[i] = bit[i];
    for (int step = 1, j = i; step < N / D; step++, j = (j + P) % N)
      v[(j + P) % N] = v[j] ^ (j + P >= N);
  }
  int i = N - 1;
  while (i >= 0 && v[i] == bit[i])
    i--;
  if (i >= 0 && bit[i] == 1)
    adto(ans, 1);
  return ans;
}

void add1() {
  int i = 0;
  while (bit[i] == 1)
    bit[i] = 0, i++;
  bit[i] = 1;
  isBig = (i == N);
}

int main() {
  // freopen ("input", "r", stdin);
  // freopen ("output", "w", stdout);

  scanf("%d\n%s", &N, initSir);
  for (int i = 0; i < N; i++)
    bit[i] = initSir[N - 1 - i] - '0';
  add1();
  p2[0] = 1;
  for (int i = 1; i <= N; i++)
    p2[i] = add(p2[i - 1], p2[i - 1]);
  int ans = 0;
  for (int i = 0; i <= N; i++)
    if (bit[i])
      adto(dp[2 * N],
           p2[i]); /// all dp is referring to numbers strictly smaller than X
  for (int i = 1; i < 2 * N; i++)
    if ((2 * N) % i == 0) {
      // printf ("%d: %d\n", i, getCount (i));
      adto(dp[i], getCount(i));
      for (int j = i + i; j <= 2 * N; j += i)
        dp[j] = subtract(dp[j], dp[i]);
    }
  for (int i = 1; i <= 2 * N; i++)
    if ((2 * N) % i == 0)
      adto(ans, mul(dp[i], i));
  printf("%d\n", ans);
  return 0;
}