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

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second
#define all(c) ((c).begin()), ((c).end())
#define sz(x) ((int)(x).size())
#define ld long double

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (int i = 0; i < (int)v.size(); i++) {
    if (i)
      os << ", ";
    os << v[i];
  }
  os << "}";
  return os;
}

#ifdef LOCAL
#define cerr cout
#else
#endif

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif
const int SQM = 729;
const int M = SQM * SQM;
int nxt[2][M], nxt2[2][SQM], nxt3[2][SQM];
int p[M];
int q[M];
char s[M];
int type[M], cnt[M];
int U = 1, V = 1, W = 1, n, MID;

int lft[M], rgt[M];

int firstBAD[SQM + 10][SQM], val[SQM + 10][SQM];
void get(int l, int r) {
  for (int i = 0; i < U; i++) {
    firstBAD[r - l + 1][i] = r - l + 1;
    val[r - l + 1][i] = i;
  }
  for (int j = r; j >= l; j--) {
    int t = type[j];
    for (int i = 0; i < U; i++) {
      int new_node = nxt2[t][i];
      if (i != U - 1 || t != 1) {
        val[j - l][i] = val[j - l + 1][new_node];
        firstBAD[j - l][i] = firstBAD[j - l + 1][new_node];
      } else {
        val[j - l][i] = i;
        firstBAD[j - l][i] = j - l;
      }
    };
  }

  for (int i = 0; i < V; i++) {
    int L = lft[i], R = rgt[i], ind = 0;
    while (ind <= r - l) {
      int nxt = firstBAD[ind][R];
      R = val[ind][R];
      L = (cnt[nxt - 1 + l] - cnt[ind - 1 + l]) & 1 ? nxt3[0][L] : L;
      if (nxt <= r - l) {
        R = 0;
        L++;
        if (L == W)
          L = 0;
      }
      ind = nxt + 1;
    }
    q[i] = L * U + R;
  }
}

int transform(int v, int k) {
  int pwr = 1, ret = 0;
  int V = v;
  for (int i = 0; i < k; i++, pwr *= 3, v /= 3) {
    int t = (2 * v) % 3;
    ret += t * pwr;
  }
  return ret;
}
int h[M];
int main() {
  // n = 10;
  sd(n);
  scanf("%s", s);
  // int m = 100000;
  int m = strlen(s);
  for (int i = 1; i <= m; i++) {
    type[i] = rand() % 2;
    type[i] = s[i - 1] == 'R';
    cnt[i] = cnt[i - 1] + 1 - type[i];
  }
  MID = (n + 1) / 2;
  for (int i = 0; i < n; i++)
    V *= 3;
  for (int i = 0; i < MID; i++)
    U *= 3;
  for (int i = 0; i < n - MID; i++)
    W *= 3;

  for (int i = 0; i < V; i++) {
    nxt[0][i] = transform(i, n);
    nxt[1][i] = (i + 1) % V;
  }

  for (int i = 0; i < U; i++) {
    nxt2[0][i] = transform(i, MID);
    nxt2[1][i] = (i + 1) % U;
  }

  for (int i = 0; i < W; i++) {
    nxt3[0][i] = transform(i, n - MID);
    nxt3[1][i] = (i + 1) % W;
  }

  for (int i = 0; i < V; i++) {
    lft[i] = i / U;
    rgt[i] = i % U;
    p[i] = i;
  }

  for (int i = 1; i <= m; i += SQM) {
    get(i, min(m + 1, i + SQM) - 1);
    for (int j = 0; j < V; j++)
      h[j] = q[p[j]];
    memcpy(p, h, sizeof p);
  }
  for (int i = 0; i < V; i++)
    printf("%d ", p[i]);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define sd(x) scanf("%d", &(x))
#define pii pair<int, int>
#define F first
#define S second
#define all(c) ((c).begin()), ((c).end())
#define sz(x) ((int)(x).size())
#define ld long double

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (int i = 0; i < (int)v.size(); i++) {
    if (i)
      os << ", ";
    os << v[i];
  }
  os << "}";
  return os;
}

#ifdef LOCAL
#define cerr cout
#else
#endif

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif
const int M = 5.5e5;
int nxt[2][M], nxt2[2][1005], nxt3[2][1005];
int p[M];
int q[M];
char s[M];
int type[M], cnt[M];
int U = 1, V = 1, W = 1, n, MID, POS;
int bad[1005];
int isBAD[1005];
int perm[1005];

int lft[M], rgt[M];

void get(int l, int r) {
  memset(isBAD, 0, sizeof isBAD);
  POS = 0;
  for (int i = 0; i < U; i++) {
    int curr = i;
    bool isBad = false;
    for (int j = l; j <= r; j++) {
      if (type[j] && curr == U - 1) {
        bad[POS++] = i;
        isBAD[i] = true;
        break;
      }
      curr = nxt2[type[j]][curr];
    }
    perm[i] = curr;
  }

  int flipped = (cnt[r] - cnt[l - 1]) & 1;
  for (int i = 0; i < V; i++) {
    int L = lft[i], R = rgt[i];
    if (isBAD[R]) {
      int curr = i;
      for (int j = l; j <= r; j++)
        curr = nxt[type[j]][curr];
      q[i] = curr;
    } else {
      q[i] = (flipped ? nxt3[0][L] : L) * U + perm[R];
    }
  }
}

int transform(int v, int k) {
  int pwr = 1, ret = 0;
  int V = v;
  for (int i = 0; i < k; i++, pwr *= 3, v /= 3) {
    int t = (2 * v) % 3;
    ret += t * pwr;
  }
  return ret;
}
int h[M];
int main() {
  sd(n);
  scanf("%s", s);
  int m = strlen(s);
  for (int i = 1; i <= m; i++) {
    type[i] = s[i - 1] == 'R';
    cnt[i] = cnt[i - 1] + 1 - type[i];
  }
  MID = (n + 1) / 2;
  for (int i = 0; i < n; i++)
    V *= 3;
  for (int i = 0; i < MID; i++)
    U *= 3;
  for (int i = 0; i < n - MID; i++)
    W *= 3;

  for (int i = 0; i < V; i++) {
    nxt[0][i] = transform(i, n);
    nxt[1][i] = (i + 1) % V;
  }

  for (int i = 0; i < U; i++) {
    nxt2[0][i] = transform(i, MID);
    nxt2[1][i] = (i + 1) % U;
  }

  for (int i = 0; i < W; i++) {
    nxt3[0][i] = transform(i, n - MID);
    nxt3[1][i] = (i + 1) % W;
  }

  for (int i = 0; i < V; i++) {
    lft[i] = i / U;
    rgt[i] = i % U;
    p[i] = i;
  }

  const int SQN = sqrt(n) + 3;

  for (int i = 1; i <= m; i += SQN) {
    get(i, min(m + 1, i + SQN) - 1);
    for (int j = 0; j < V; j++)
      h[j] = q[p[j]];
    memcpy(p, h, sizeof p);
  }

  for (int i = 0; i < V; i++)
    printf("%d ", p[i]);
}