Problem p02671 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

const int max_n = 200222, inf = 1000111222;
const int max_tot = 729 * 729;
const int max_half = 729;
const int max_big = max_tot / max_half;

char buf[max_n];

string read() {
  scanf("%s", buf);
  return buf;
}

int n, nxt[max_n][max_half];
int prec[max_half], ans[max_tot], res[max_big];
int sum[max_n];
int pw;

int get_sum(int l, int r) {
  if (!l) {
    return sum[r];
  }
  return sum[r] - sum[l - 1];
}

void get_all_prec() {
  pw = 1;
  for (int i = 0; i < n; ++i) {
    pw *= 3;
  }
  for (int x = 0; x < pw; ++x) {
    vector<int> v;
    int cur = x;
    for (int i = 0; i < n; ++i) {
      v.push_back(cur % 3);
      cur /= 3;
    }
    reverse(v.begin(), v.end());
    int to = 0;
    for (int i = 0; i < n; ++i) {
      int x = (v[i] * 2) % 3;
      to = to * 3 + x;
    }
    prec[x] = to;
  }
}

const bool debug = 0;

int main() {
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
  string s;
  if (debug) {
    mt19937 gen;
    n = 12;
    for (int i = 0; i < 200000; ++i) {
      s += "SR"[gen() % 2];
    }
  } else {
    scanf("%d", &n);
    s = read();
  }
  get_all_prec();
  const int half = min(max_half, pw);
  for (int x = 0; x < half; ++x) {
    nxt[s.length()][x] = -1 - x;
  }
  for (int i = 0; i < s.length(); ++i) {
    sum[i] = s[i] == 'S';
    if (i) {
      sum[i] += sum[i - 1];
    }
  }
  int tot = 0;
  for (int i = s.length() - 1; i >= 0; --i) {
    for (int x = 0; x < half; ++x) {
      int to = prec[x];
      if (s[i] == 'R') {
        to = x + 1;
      }
      if (to == half) {
        nxt[i][x] = i;
      } else {
        nxt[i][x] = nxt[i + 1][to];
      }
      tot += nxt[i][x];
      // cout << nxt[i][x] << " ";
    }
    // cout << endl;
  }
  int mx = pw / half;
  for (int ismall = 0; ismall < half; ++ismall) {
    for (int big = 0; big < mx; ++big) {
      res[big] = big;
    }
    int small = ismall;
    int pos = 0;
    while (pos < s.length()) {
      // cout << pos << ": " << big << " " << small << endl;
      if (nxt[pos][small] < 0) {
        small = -1 - nxt[pos][small];
        if (get_sum(pos, s.length() - 1) % 2) {
          for (int big = 0; big < mx; ++big) {
            res[big] = prec[res[big]];
          }
        }
        pos = s.length();
      } else {
        int to = nxt[pos][small];
        if (get_sum(pos, to) % 2) {
          for (int big = 0; big < mx; ++big) {
            res[big] = prec[res[big]] + 1;
            if (res[big] == mx) {
              res[big] = 0;
            }
          }
        } else {
          for (int big = 0; big < mx; ++big) {
            res[big] = res[big] + 1;
            if (res[big] == mx) {
              res[big] = 0;
            }
          }
        }
        small = 0;
        pos = to + 1;
      }
    }
    for (int big = 0; big < mx; ++big) {
      ans[big * half + ismall] = res[big] * half + small;
    }
  }
  for (int i = 0; i < pw; ++i) {
    printf("%d ", ans[i]);
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int max_n = 200222, inf = 1000111222;
const int max_half = 729;

char buf[max_n];

string read() {
  scanf("%s", buf);
  return buf;
}

int n, nxt[max_n][max_half], ans[max_n];
int prec[max_half];
int sum[max_n];
int pw;

int get_sum(int l, int r) {
  if (!l) {
    return sum[r];
  }
  return sum[r] - sum[l - 1];
}

void get_all_prec() {
  pw = 1;
  for (int i = 0; i < n; ++i) {
    pw *= 3;
  }
  for (int x = 0; x < pw; ++x) {
    vector<int> v;
    int cur = x;
    for (int i = 0; i < n; ++i) {
      v.push_back(cur % 3);
      cur /= 3;
    }
    reverse(v.begin(), v.end());
    int to = 0;
    for (int i = 0; i < n; ++i) {
      int x = (v[i] * 2) % 3;
      to = to * 3 + x;
    }
    prec[x] = to;
  }
}

int main() {
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
  scanf("%d", &n);
  get_all_prec();
  const int half = min(max_half, pw);
  string s = read();
  for (int x = 0; x < half; ++x) {
    nxt[s.length()][x] = -1 - x;
  }
  for (int i = 0; i < s.length(); ++i) {
    sum[i] = s[i] == 'S';
    if (i) {
      sum[i] += sum[i - 1];
    }
  }
  for (int i = s.length() - 1; i >= 0; --i) {
    for (int x = 0; x < half; ++x) {
      int to = prec[x];
      if (s[i] == 'R') {
        to = x + 1;
      }
      if (to == half) {
        nxt[i][x] = i;
      } else {
        nxt[i][x] = nxt[i + 1][to];
      }
      // cout << nxt[i][x] << " ";
    }
    // cout << endl;
  }
  int mx = pw / half;
  for (int x = 0; x < pw; ++x) {
    int big = x / half, small = x % half;
    int pos = 0;
    while (pos < s.length()) {
      // cout << pos << ": " << big << " " << small << endl;
      if (nxt[pos][small] < 0) {
        small = -1 - nxt[pos][small];
        if (get_sum(pos, s.length() - 1) % 2) {
          big = prec[big];
        }
        pos = s.length();
      } else {
        int to = nxt[pos][small];
        if (get_sum(pos, to) % 2) {
          big = prec[big];
        }
        ++big;
        if (big == mx) {
          big = 0;
        }
        small = 0;
        pos = to + 1;
      }
    }
    printf("%d ", big * half + small);
    // cout << endl;
  }
  return 0;
}