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

/**
 * @brief atcoder
 * @author yao
 */
#include <algorithm>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <utility>
#define ft first
#define sd second
#ifdef DBG
#define dbg_pri(x...) fprintf(stderr, x)
#else
#define dbg_pri(x...) 0
#define NDEBUG
#endif // DBG
#include <cassert>

typedef unsigned int uint;
typedef long long int lli;
typedef unsigned long long int ulli;

#define N 524288
#define M 16

const int p3[M] = {1,      3,       9,       27,      81,    243,
                   729,    2187,    6561,    19683,   59049, 177147,
                   531441, 1594323, 4782969, 14348907};
const int op_add[2][3] = {{1, 2, 0}, {2, 0, 1}};
const int conv[2][3] = {{0, 1, 2}, {0, 2, 1}};
int a[M][N];
int dir = 0;
char s[N];
int n, m;

void add(int x, int y) {
  if (y == m)
    return;
  for (int i = 0; i < 3; ++i) {
    int pos = x + p3[y] * i;
    a[y][pos] = op_add[dir][a[y][pos]];
    if (a[y][pos] == 0)
      add(pos, y + 1);
  }
}

int main() {
  scanf("%d%s", &m, s), n = p3[m];
  for (int i = 0; i < m; ++i)
    for (int j = 0; j < p3[i + 1]; ++j)
      a[i][j] = j / p3[i];
  for (int i = 0; s[i]; ++i) {
    if (s[i] == 'S')
      dir ^= 1;
    if (s[i] == 'R')
      add(0, 0);
  }
  for (int i = 0; i < n; ++i) {
    int res = 0;
    for (int j = 0; j < m; ++j)
      res += conv[dir][a[j][i % p3[j + 1]]] * p3[j];
    printf("%d%c", res, i == n - 1 ? '\\n' : ' ');
  }
  return 0;
}


Error: TLE

Fixed submission:

/**
 * @brief atcoder
 * @author yao
 */
#include <algorithm>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <utility>
#define ft first
#define sd second
#ifdef DBG
#define dbg_pri(x...) fprintf(stderr, x)
#else
#define dbg_pri(x...) 0
#define NDEBUG
#endif // DBG
#include <cassert>

typedef unsigned int uint;
typedef long long int lli;
typedef unsigned long long int ulli;

#define N 1048576

struct Treap {
  Treap *l, *r;
  int v, w;
  Treap() {}
  Treap(int _v) : l(0), r(0), v(_v), w(1) {}
};

int get_w(Treap *p) { return p ? p->w : 0; }

void pull(Treap *p) { p->w = 1 + get_w(p->l) + get_w(p->r); }

Treap *merge(Treap *p, Treap *q) {
  if (!p || !q)
    return p ? p : q;
  return rand() % (p->w + q->w) < p->w ? (p->r = merge(p->r, q), pull(p), p)
                                       : (q->l = merge(p, q->l), pull(q), q);
}

std::pair<Treap *, Treap *> split(Treap *p, int k) {
  if (!p)
    return {0, 0};
  if (!k)
    return {0, p};
  if (p->w <= k)
    return {p, 0};
  Treap *l, *m, *r;
  int lw = get_w(p->l);
  if (lw < k)
    std::tie(m, r) = split(p->r, k - lw - 1), p->r = 0, pull(p),
                l = merge(p, m);
  else
    std::tie(l, m) = split(p->l, k), p->l = 0, pull(p), r = merge(m, p);
  return {l, r};
}

struct TT {
  static TT pool[N];
  static int n;
  TT *l, *m, *r;
  Treap *p;
  int w, lz;
  TT() : l(0), r(0), p(0), w(0), lz(0) {}
};

TT TT::pool[N];
int TT::n = 0;

void tt_push(TT *p);

TT *tt_append(TT *p, Treap *q) {
  if (!q)
    return p;
  if (!p)
    p = new (&TT::pool[TT::n++]) TT();
  tt_push(p);
  p->w += get_w(q);
  p->p = merge(p->p, q);
  return p;
}

Treap *tt_cut(TT *p, int k) {
  if (!p)
    return 0;
  tt_push(p);
  Treap *res = 0;
  Treap *l;
  l = tt_cut(p->l, k), k -= get_w(l), res = merge(res, l);
  l = tt_cut(p->m, k), k -= get_w(l), res = merge(res, l);
  l = tt_cut(p->r, k), k -= get_w(l), res = merge(res, l);
  std::tie(l, p->p) = split(p->p, k), res = merge(res, l);
  p->w -= get_w(res);
  return res;
}

void tt_push(TT *p) {
  if (!p->lz)
    return;
  assert(p->w % 3 == 0);
  int k = p->w / 3;
  Treap *l = p->p;
  p->p = 0;
  p->r = tt_append(p->r, l);
  l = tt_cut(p->r, p->r->w - k);
  p->m = tt_append(p->m, l);
  l = tt_cut(p->m, p->m->w - k);
  p->l = tt_append(p->l, l);
  assert(p->l->w == k);
  std::swap(p->l, p->m);
  p->lz ^= 1;
  if (k != 1)
    p->l->lz ^= 1, p->m->lz ^= 1, p->r->lz ^= 1;
}

char s[N];
Treap node[N];

int ans[N];

int main() {
  int n = 1, m;
  scanf("%d%s", &m, s);
  for (int i = 0; i < m; ++i)
    n *= 3;
  TT *rt = 0;
  for (int i = n - 1; i >= 0; --i)
    node[i] = Treap(i), rt = tt_append(rt, &node[i]);
  for (int i = 0; s[i]; ++i) {
    dbg_pri("poi 1: %d %c\\n", i, s[i]);
    if (s[i] == 'S') {
      rt->lz ^= 1;
    }
    if (s[i] == 'R') {
      Treap *p = tt_cut(rt, 1);
      rt = tt_append(rt, p);
    }
#ifdef DBG
    for (int i = n - 1; i >= 0; --i) {
      Treap *p = tt_cut(rt, 1);
      rt = tt_append(rt, p);
      ans[i] = p->v;
    }
    dbg_pri("poi 2:");
    for (int i = 0; i < n; ++i)
      dbg_pri(" %d", ans[i]);
    dbg_pri("\\n");
#endif // DBG
    assert(s[i] == 'S' || s[i] == 'R');
  }
  for (int i = n - 1; i >= 0; --i) {
    Treap *p = tt_cut(rt, 1);
    assert(p);
    ans[p->v] = i;
  }
  assert(rt->w == 0);
  for (int i = 0; i < n; ++i)
    printf("%d%c", ans[i], i == n - 1 ? '\\n' : ' ');
  return 0;
}