Problem p03051 (C++)

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

#define MN 1001000
#define MOD 1000000007

using namespace std;
typedef long long ll;

ll n, ans, a[MN], txor, ac[MN], dp[MN], adp[MN];
vector<int> occ[MN];

ll zs(int l, int r) {
  int L = lower_bound(occ[0].begin(), occ[0].end(), l) - occ[0].begin();
  int R = lower_bound(occ[0].begin(), occ[0].end(), r) - occ[0].begin();
  return R - L;
}

ll p[MN][2];
ll solve(int pos, int empt) {
  if (pos > n)
    return !empt;

  ll &x = p[pos][empt];
  if (x != -1)
    return x;
  x = 0;

  ll xo = a[pos], j = pos;
  while (xo != 0) {
    xo ^= a[++j];
  }

  x = (solve(j + 1, 0) + solve(j + 1, 1)) % MOD;
  return x;
}

int main() {
  scanf("%lld", &n);
  memset(p, -1, sizeof p);

  for (int i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
    txor ^= a[i];
  }

  a[0] = ac[0] = txor;
  occ[txor].push_back(0);
  for (int i = 1; i <= n; i++) {
    txor ^= a[i];
    ac[i] = txor;
    occ[txor].push_back(i);
  }
  txor = ac[0];

  dp[n + 1] = 0;
  for (int i = n; i > 0; i--) {
    int ai = ac[i - 1];
    int l =
        lower_bound(occ[ai].begin(), occ[ai].end(), i - 1) - occ[ai].begin();
    int r = l + 1;

    assert(l < occ[ai].size() && occ[ai][l] == i - 1);

    if (r == occ[ai].size())
      dp[i] = 1, adp[i] = 1;
    else {
      ll z = zs(i, occ[ai][r]);
      dp[i] = (dp[occ[ai][r] + 1] + z * adp[occ[ai][r] + 1]) % MOD;
      adp[i] = (adp[occ[ai][r] + 1] + dp[i]) % MOD;
    }
  }

  if (txor == 0) {
    for (int i = 1; i + 1 <= n; i++) {
      if (ac[i])
        ans += dp[i + 1];
      if (ans >= MOD)
        ans -= MOD;
    }
    ans += solve(1, 0);
    if (ans >= MOD)
      ans -= MOD;
  } else
    ans = dp[1];

  printf("%lld\n", ans);
  return 0;
}


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

#define MN 2001000
#define MOD 1000000007

using namespace std;
typedef long long ll;

ll n, ans, a[MN], txor, ac[MN], dp[MN], adp[MN];
vector<int> occ[MN];

ll zs(int l, int r) {
  int L = lower_bound(occ[0].begin(), occ[0].end(), l) - occ[0].begin();
  int R = lower_bound(occ[0].begin(), occ[0].end(), r) - occ[0].begin();
  return R - L;
}

ll p[MN][2];
ll solve(int pos, int empt) {
  if (pos > n)
    return !empt;

  ll &x = p[pos][empt];
  if (x != -1)
    return x;
  x = 0;

  ll xo = a[pos], j = pos;
  while (xo != 0) {
    xo ^= a[++j];
  }

  x = (solve(j + 1, 0) + solve(j + 1, 1)) % MOD;
  return x;
}

int main() {
  scanf("%lld", &n);
  memset(p, -1, sizeof p);

  for (int i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
    txor ^= a[i];
  }

  a[0] = ac[0] = txor;
  occ[txor].push_back(0);
  for (int i = 1; i <= n; i++) {
    txor ^= a[i];
    ac[i] = txor;
    occ[txor].push_back(i);
  }
  txor = ac[0];

  dp[n + 1] = 0;
  for (int i = n; i > 0; i--) {
    int ai = ac[i - 1];
    int l =
        lower_bound(occ[ai].begin(), occ[ai].end(), i - 1) - occ[ai].begin();
    int r = l + 1;

    assert(l < occ[ai].size() && occ[ai][l] == i - 1);

    if (r == occ[ai].size())
      dp[i] = 1, adp[i] = 1;
    else {
      ll z = zs(i, occ[ai][r]);
      dp[i] = (dp[occ[ai][r] + 1] + z * adp[occ[ai][r] + 1]) % MOD;
      adp[i] = (adp[occ[ai][r] + 1] + dp[i]) % MOD;
    }
  }

  if (txor == 0) {
    for (int i = 1; i + 1 <= n; i++) {
      if (ac[i])
        ans += dp[i + 1];
      if (ans >= MOD)
        ans -= MOD;
    }
    ans += solve(1, 0);
    if (ans >= MOD)
      ans -= MOD;
  } else
    ans = dp[1];

  printf("%lld\n", ans);
  return 0;
}