Problem p03051 (C++)

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

using namespace std;

#define ll long long
#define MOD 1000000007

int n;
int a[500001];
int b[500002];
int zerob[500003];

vector<int> xat[1 << 20];
map<int, ll> dp[2];

int getNextX(int at, int tarX) {
  vector<int> target = xat[tarX];
  vector<int>::iterator position =
      lower_bound(target.begin(), target.end(), at);
  if (position == target.end())
    return n;
  return *position;
}

int getXnum(int l, int r, int tarX) {
  vector<int> target = xat[tarX];
  vector<int>::iterator posA = lower_bound(target.begin(), target.end(), l);
  vector<int>::iterator posB = lower_bound(target.begin(), target.end(), r);
  return posB - posA;
}

int get0num(int l, int r) { return zerob[r] - zerob[l]; }

int main() {
  cin >> n;
  // srand((unsigned)time(NULL));
  // n = 500000;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    // a[i] = i%40;
    // a[i] = (1<<20)-1;
  }
  b[0] = 0;
  for (int i = 0; i < n; i++) {
    b[i + 1] = b[i] ^ a[i];
  }
  n++;
  if (b[n - 1] == 0)
    return 1;
  zerob[0] = 0;
  for (int i = 0; i < n; i++) {
    xat[b[i]].push_back(i);
    zerob[i + 1] = zerob[i] + (b[i] == 0 ? 1 : 0);
  }
  // for(int i = 0;i < n;i++){
  // 	cout << b[i] << " ";
  // }
  // cout << endl;
  // for(int i = 0;i < n;i++){
  // 	cout << zerob[i] << " ";
  // }
  // cout << endl;
  ll ans = 0;
  map<int, int> fin;
  for (int i = 0; i < n; i++) {
    int X = b[i];
    if (X == 0)
      continue;
    if (fin[X] == 1)
      continue;
    if (b[n - 1] != 0 && b[n - 1] != X)
      continue;
    // cout << X << endl;
    fin[X] = 1;

    vector<pair<int, int>> target;
    int index_last = 0;
    int count = 1;
    if (b[n - 1] == 0)
      xat[X].push_back(n); // 番兵
    target.push_back(make_pair(0, 1));
    // cout << xat[X].size() <<endl;
    for (int j = 1; j < xat[X].size(); j++) { // 座標圧縮
      int at = xat[X][j];
      // cout << at << " ";
      int num0 = get0num(xat[X][index_last], at);
      if (num0 == 0) {
        count++;
        continue;
      }
      target.push_back(make_pair(X, count));
      target.push_back(make_pair(0, num0));
      index_last = j;
      count = 1;
    }
    if (b[n - 1] != 0)
      target.push_back(make_pair(X, count));
    // cout << endl;
    // cout << X << endl;
    // for(int j = 0;j < target.size();j++){
    // 	cout << target[j].first << " " << target[j].second << endl;
    // }

    dp[0].clear();
    dp[1].clear();
    int n2 = target.size();
    dp[0][n2 - 1] = b[n - 1] == 0 ? 0 : 1;
    dp[1][n2 - 1] = (dp[0][n2 - 1] + 1) % 2;
    for (int at = n2 - 2; at != -1; at--) {
      for (int before = 0; before < 2; before++) {
        // cout << at << endl;
        dp[before][at] = 0;
        dp[before][at] += dp[before][at + 1];
        int y = target[at].first;
        int len = target[at].second;
        if (y == 0 && before == 1) {
          dp[before][at] += dp[0][at + 1] * len % MOD; // 選ぶ
        } else if (y != 0 && before == 0) {
          dp[before][at] += dp[1][at + 1] * len % MOD; // 選ぶ
        }
        dp[before][at] %= MOD;
      }
    }
    ans += dp[0][0];
    ans %= MOD;
  }
  if (b[n - 1] != 0) {
    cout << ans << endl;
    return 0;
  }
  int num0 = getXnum(0, n, 0);
  ll ans0 = 1;
  for (int i = 0; i < num0 - 2; i++) {
    ans0 *= 2;
    ans0 %= MOD;
  }
  cout << (ans0 + ans) % MOD << endl;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <vector>

using namespace std;

#define ll long long
#define MOD 1000000007

int n;
int a[500001];
int b[500002];
int zerob[500003];

vector<int> xat[1 << 20];
map<int, ll> dp[2];

int getNextX(int at, int tarX) {
  vector<int> target = xat[tarX];
  vector<int>::iterator position =
      lower_bound(target.begin(), target.end(), at);
  if (position == target.end())
    return n;
  return *position;
}

int getXnum(int l, int r, int tarX) {
  vector<int> target = xat[tarX];
  vector<int>::iterator posA = lower_bound(target.begin(), target.end(), l);
  vector<int>::iterator posB = lower_bound(target.begin(), target.end(), r);
  return posB - posA;
}

int get0num(int l, int r) { return zerob[r] - zerob[l]; }

int main() {
  cin >> n;
  // srand((unsigned)time(NULL));
  // n = 500000;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    // a[i] = i%40;
    // a[i] = (1<<20)-1;
  }
  b[0] = 0;
  for (int i = 0; i < n; i++) {
    b[i + 1] = b[i] ^ a[i];
  }
  n++;
  zerob[0] = 0;
  for (int i = 0; i < n; i++) {
    xat[b[i]].push_back(i);
    zerob[i + 1] = zerob[i] + (b[i] == 0 ? 1 : 0);
  }
  // for(int i = 0;i < n;i++){
  // 	cout << b[i] << " ";
  // }
  // cout << endl;
  // for(int i = 0;i < n;i++){
  // 	cout << zerob[i] << " ";
  // }
  // cout << endl;
  ll ans = 0;
  map<int, int> fin;
  for (int i = 0; i < n; i++) {
    int X = b[i];
    if (X == 0)
      continue;
    if (fin[X] == 1)
      continue;
    if (b[n - 1] != 0 && b[n - 1] != X)
      continue;
    // cout << X << endl;
    fin[X] = 1;

    vector<pair<int, int>> target;
    int index_last = 0;
    int count = 1;
    if (b[n - 1] == 0)
      xat[X].push_back(n); // 番兵
    target.push_back(make_pair(0, 1));
    // cout << xat[X].size() <<endl;
    for (int j = 1; j < xat[X].size(); j++) { // 座標圧縮
      int at = xat[X][j];
      // cout << at << " ";
      int num0 = get0num(xat[X][index_last], at);
      if (num0 == 0) {
        count++;
        continue;
      }
      target.push_back(make_pair(X, count));
      target.push_back(make_pair(0, num0));
      index_last = j;
      count = 1;
    }
    if (b[n - 1] != 0)
      target.push_back(make_pair(X, count));
    // cout << endl;
    // cout << X << endl;
    // for(int j = 0;j < target.size();j++){
    // 	cout << target[j].first << " " << target[j].second << endl;
    // }

    dp[0].clear();
    dp[1].clear();
    int n2 = target.size();
    dp[0][n2 - 1] = b[n - 1] == 0 ? 0 : 1;
    dp[1][n2 - 1] = (dp[0][n2 - 1] + 1) % 2;
    for (int at = n2 - 2; at != -1; at--) {
      for (int before = 0; before < 2; before++) {
        // cout << at << endl;
        dp[before][at] = 0;
        dp[before][at] += dp[before][at + 1];
        int y = target[at].first;
        int len = target[at].second;
        if (y == 0 && before == 1) {
          dp[before][at] += dp[0][at + 1] * len % MOD; // 選ぶ
        } else if (y != 0 && before == 0) {
          dp[before][at] += dp[1][at + 1] * len % MOD; // 選ぶ
        }
        dp[before][at] %= MOD;
      }
    }
    ans += dp[0][0];
    ans %= MOD;
  }
  if (b[n - 1] != 0) {
    cout << ans << endl;
    return 0;
  }
  int num0 = getXnum(0, n, 0);
  ll ans0 = 1;
  for (int i = 0; i < num0 - 2; i++) {
    ans0 *= 2;
    ans0 %= MOD;
  }
  cout << (ans0 + ans) % MOD << endl;
}