Problem p02671 (C++) — buggy submission, verdict: Runtime Error

#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;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    pbds;

int a[555555];
int nxt[200111]
       [739]; // if we start with j before operation i, what is the next command
              // s.t. after performing it, we get 000000 (-1 if doesn't exist)
int p3[13];
const int LG = 10;
int dp[739][(1 << LG) + 1];
int flipprep[739];

int flip(int x) {
  int ans = 0;
  int cur = 1;
  while (x > 0) {
    int d = x % 3;
    if (d == 1)
      d = 2;
    else if (d == 2)
      d = 1;
    ans += cur * d;
    x /= 3;
    cur *= 3;
  }
  return ans;
}

int ans[555555];
int Spref[255555];

int ssum(int l, int r) {
  if (l == 0)
    return Spref[r];
  else
    return Spref[r] - Spref[l - 1];
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  // freopen("strange-dance-1.out","w",stdout);
  // freopen("strange-dance.in","r",stdin);
  int n;
  cin >> n;
  string s;
  cin >> s;
  p3[0] = 1;
  for (int i = 1; i <= 12; i++)
    p3[i] = p3[i - 1] * 3;
  for (int i = 0; i < 730; i++) {
    flipprep[i] = flip(i);
    // cerr<<i<<' '<<flipprep[i]<<'\\n';
    // if(i<729) assert(flipprep[i]<729);
  }
  int m = s.length();
  for (int i = 0; i < m; i++) {
    Spref[i] = (s[i] == 'S');
    if (i > 0)
      Spref[i] += Spref[i - 1];
  }
  if (n <= 1) {
    for (int i = 0; i < p3[n]; i++) {
      int cur = i;
      for (int j = 0; j < m; j++) {
        if (s[j] == 'R') {
          cur++;
          cur %= p3[n];
        } else
          cur = flip(cur);
      }
      ans[i] = cur;
    }
    for (int i = 0; i < p3[n]; i++) {
      cout << ans[i];
      if (i + 1 < p3[n])
        cout << ' ';
    }
    cout << '\\n';
    return 0;
  }
  int l = n / 2;
  // last l bits
  for (int i = 0; i < p3[l]; i++) {
    nxt[m][i] = nxt[m - 1][i] = -1;
    if (i == p3[l] - 1 && s[m - 1] == 'R')
      nxt[m - 1][i] = m - 1;
  }
  for (int i = m - 2; i >= 0; i--) {
    for (int j = 0; j < p3[l]; j++) {
      if (j == p3[l] - 1 && s[i] == 'R') {
        nxt[i][j] = i;
      } else {
        int nxtbit = j + 1;
        if (s[i] == 'S')
          nxtbit = flipprep[j];
        nxt[i][j] = nxt[i + 1][nxtbit];
      }
    }
  }
  int r = n - l;
  // for every first r bits, and a binary string, i want to know its new value
  // fast
  for (int i = 0; i < p3[r]; i++) {
    for (int j = 0; j < (1 << LG);
         j++) // this means (bit0,+), (bit1,+), (bit2,+), ..., (bitLG-1, +)
    {
      int cur = i;
      for (int k = 0; k < LG; k++) {
        if (j & (1 << k)) {
          cur = flipprep[cur];
        }
        cur++;
        if (cur >= p3[r])
          cur -= p3[r];
      }
      dp[i][j] = cur;
      // assert(cur<p3[r]&&cur>=0);
    }
  }
  // now, I iterate over all last l bits
  for (int i = 0; i < p3[l]; i++) {
    int finv = i;
    for (int j = 0; j < m; j++) {
      if (s[j] == 'R')
        finv++;
      else
        finv = flipprep[finv];
      if (finv >= p3[l])
        finv -= p3[l];
    }
    // form the bit string
    int val = i; // of course, I start from i
    vector<int> bitstring;
    int pos = 0;
    int undo = 0;
    while (pos < m) {
      int nxtpos = nxt[pos][val];
      // done operations from pos to nxtpos
      if (nxtpos != -1) {
        bitstring.pb(ssum(pos, nxtpos) & 1);
        pos = nxtpos + 1;
        val = 0;
      } else {
        bitstring.pb(ssum(pos, m - 1) & 1);
        undo = 1;
        break;
      }
    }
    vector<int> compressed;
    int curbit = 0;
    int curmult = 1;
    // cerr<<"I = "<<i<<": ";
    vi remstring;
    for (int v : bitstring) {
      // cerr<<v<<' ';
      remstring.pb(v);
      curbit += curmult * v;
      curmult *= 2;
      if (curmult >= (1 << LG)) {
        compressed.pb(curbit);
        assert(curbit < (1 << LG));
        remstring.clear();
        curmult = 1;
        curbit = 0;
      }
    }
    // cerr<<'\\n';
    // cerr<<"UNDO = "<<undo<<'\\n';
    for (int j = 0; j < p3[r]; j++) {
      int prefval = j;
      for (int v : compressed) {
        prefval = dp[prefval][v];
      }
      for (int v : remstring) {
        // cerr<<v<<' '<<prefval<<'\\n';
        if (v) {
          prefval = flipprep[prefval];
        }
        prefval++;
        if (prefval >= p3[r])
          prefval -= p3[r];
      }
      // cerr<<'\\n';
      // cerr<<"J = "<<j<<" PREFVAL = "<<prefval<<'\\n';
      if (undo) {
        prefval--;
        if (prefval < 0)
          prefval += p3[r];
      }
      int val = prefval * p3[l] + finv;
      int lab = j * p3[l] + i;
      assert(lab >= 0 && lab < p3[n] && val >= 0 && val < p3[n]);
      ans[lab] = val;
    }
  }
  set<int> S;
  for (int i = 0; i < p3[n]; i++) {
    cout << ans[i];
    S.insert(ans[i]);
    if (i + 1 < p3[n])
      cout << ' ';
  }
  assert(S.size() == p3[n]);
  cout << '\\n';
}


Error: -11

Fixed submission:

#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;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    pbds;

int a[555555];
int nxt[200111]
       [739]; // if we start with j before operation i, what is the next command
              // s.t. after performing it, we get 000000 (-1 if doesn't exist)
int p3[13];
const int LG = 10;
int dp[739][(1 << LG) + 1];
int flipprep[739];

int flip(int x) {
  int ans = 0;
  int cur = 1;
  while (x > 0) {
    int d = x % 3;
    if (d == 1)
      d = 2;
    else if (d == 2)
      d = 1;
    ans += cur * d;
    x /= 3;
    cur *= 3;
  }
  return ans;
}

int ans[555555];
int Spref[255555];

int ssum(int l, int r) {
  if (l == 0)
    return Spref[r];
  else
    return Spref[r] - Spref[l - 1];
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  string s;
  cin >> s;
  p3[0] = 1;
  for (int i = 1; i <= 12; i++)
    p3[i] = p3[i - 1] * 3;
  for (int i = 0; i < 730; i++)
    flipprep[i] = flip(i);
  int m = s.length();
  for (int i = 0; i < m; i++) {
    Spref[i] = (s[i] == 'S');
    if (i > 0)
      Spref[i] += Spref[i - 1];
  }
  if (n <= 1) {
    for (int i = 0; i < p3[n]; i++) {
      int cur = i;
      for (int j = 0; j < m; j++) {
        if (s[j] == 'R') {
          cur++;
          cur %= p3[n];
        } else
          cur = flip(cur);
      }
      ans[i] = cur;
    }
    for (int i = 0; i < p3[n]; i++) {
      cout << ans[i];
      if (i + 1 < p3[n])
        cout << ' ';
    }
    cout << '\\n';
    return 0;
  }
  int l = n / 2;
  // last l bits
  for (int i = 0; i < p3[l]; i++) {
    nxt[m][i] = nxt[m - 1][i] = -1;
    if (i == p3[l] - 1 && s[m - 1] == 'R')
      nxt[m - 1][i] = m - 1;
  }
  for (int i = m - 2; i >= 0; i--) {
    for (int j = 0; j < p3[l]; j++) {
      if (j == p3[l] - 1 && s[i] == 'R') {
        nxt[i][j] = i;
      } else {
        int nxtbit = j + 1;
        if (s[i] == 'S')
          nxtbit = flipprep[j];
        nxt[i][j] = nxt[i + 1][nxtbit];
      }
    }
  }
  int r = n - l;
  // for every first r bits, and a binary string, i want to know its new value
  // fast
  for (int i = 0; i < p3[r]; i++) {
    for (int j = 0; j < (1 << LG);
         j++) // this means (bit0,+), (bit1,+), (bit2,+), ..., (bitLG-1, +)
    {
      int cur = i;
      for (int k = 0; k < LG; k++) {
        if (j & (1 << k)) {
          cur = flipprep[cur];
        }
        cur++;
        if (cur >= p3[r])
          cur -= p3[r];
      }
      dp[i][j] = cur;
    }
  }
  // now, I iterate over all last l bits
  for (int i = 0; i < p3[l]; i++) {
    int finv = i;
    for (int j = 0; j < m; j++) {
      if (s[j] == 'R')
        finv++;
      else
        finv = flipprep[finv];
      if (finv >= p3[l])
        finv -= p3[l];
    }
    // form the bit string
    int val = i; // of course, I start from i
    vector<int> bitstring;
    int pos = 0;
    int undo = 0;
    while (pos < m) {
      int nxtpos = nxt[pos][val];
      // done operations from pos to nxtpos
      if (nxtpos != -1) {
        bitstring.pb(ssum(pos, nxtpos) & 1);
        pos = nxtpos + 1;
        val = 0;
      } else {
        bitstring.pb(ssum(pos, m - 1) & 1);
        undo = 1;
        break;
      }
    }
    vector<int> compressed;
    int curbit = 0;
    int curmult = 1;
    // cerr<<"I = "<<i<<": ";
    vi remstring;
    for (int v : bitstring) {
      // cerr<<v<<' ';
      remstring.pb(v);
      curbit += curmult * v;
      curmult *= 2;
      if (curmult >= (1 << LG)) {
        compressed.pb(curbit);
        remstring.clear();
        curmult = 1;
      }
    }
    // cerr<<'\\n';
    // cerr<<"UNDO = "<<undo<<'\\n';
    for (int j = 0; j < p3[r]; j++) {
      int prefval = j;
      for (int v : compressed) {
        prefval = dp[prefval][v];
      }
      for (int v : remstring) {
        // cerr<<v<<' '<<prefval<<'\\n';
        if (v) {
          prefval = flipprep[prefval];
        }
        prefval++;
        if (prefval >= p3[r])
          prefval -= p3[r];
      }
      // cerr<<'\\n';
      // cerr<<"J = "<<j<<" PREFVAL = "<<prefval<<'\\n';
      if (undo) {
        prefval--;
        if (prefval < 0)
          prefval += p3[r];
      }
      int val = prefval * p3[l] + finv;
      int lab = j * p3[l] + i;
      ans[lab] = val;
    }
  }
  for (int i = 0; i < p3[n]; i++) {
    cout << ans[i];
    if (i + 1 < p3[n])
      cout << ' ';
  }
  cout << '\\n';
}