Problem p02671 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

inline int read() {
  int ret = 0, t = 1;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-')
    c = getchar();
  if (c == '-')
    t = -1, c = getchar();
  while (c >= '0' && c <= '9')
    ret = ret * 10 + c - '0', c = getchar();
  return ret * t;
}

#define PR pair<int, int>
#define MP make_pair
#define TO first
#define NUM second

int n;
const int MAXN = 600600;
struct tree {
  PR s[3];
  int val;
  bool lazy;
} t[MAXN];
int top = 1;

void build(int x, int st, int tmp, int val) {
  if (st == n) {
    t[x].val = val;
    return;
  }
  t[x].s[0] = MP(++top, 0);
  build(t[x].s[0].TO, st + 1, tmp * 3, val + tmp * 0);
  t[x].s[1] = MP(++top, 1);
  build(t[x].s[1].TO, st + 1, tmp * 3, val + tmp * 1);
  t[x].s[2] = MP(++top, 2);
  build(t[x].s[2].TO, st + 1, tmp * 3, val + tmp * 2);
}

PR fnd(int x) {
  int u, v;
  if (t[x].s[0].NUM == 1)
    u = 0;
  if (t[x].s[1].NUM == 1)
    u = 1;
  if (t[x].s[2].NUM == 1)
    u = 2;
  if (t[x].s[0].NUM == 2)
    v = 0;
  if (t[x].s[1].NUM == 2)
    v = 1;
  if (t[x].s[2].NUM == 2)
    v = 2;
  return MP(u, v);
}

void pushdown(int x) {
  if (!t[x].lazy)
    return;
  t[x].lazy = false;
  for (int i = 0; i < 3; i++) {
    PR tmp = fnd(t[x].s[i].TO);
    int rua = t[x].s[i].TO;
    swap(t[rua].s[tmp.first].NUM, t[rua].s[tmp.second].NUM);
  }
  t[t[x].s[0].TO].lazy ^= 1, t[t[x].s[1].TO].lazy ^= 1,
      t[t[x].s[2].TO].lazy ^= 1;
}

void mod1(int x) {
  if (!t[x].s[0].TO)
    return;
  pushdown(x);
  ++t[x].s[0].NUM, ++t[x].s[1].NUM, ++t[x].s[2].NUM;
  if (t[x].s[0].NUM == 3)
    t[x].s[0].NUM = 0, mod1(t[x].s[0].TO);
  if (t[x].s[1].NUM == 3)
    t[x].s[1].NUM = 0, mod1(t[x].s[1].TO);
  if (t[x].s[2].NUM == 3)
    t[x].s[2].NUM = 0, mod1(t[x].s[2].TO);
}

void mod2(int x) {
  if (!t[x].s[0].TO)
    return;
  PR tmp = fnd(x);
  swap(t[x].s[tmp.first].NUM, t[x].s[tmp.second].NUM);
  t[x].lazy ^= 1;
}

int ans[MAXN];
void query(int x, int st, int val) {
  if (!t[x].s[0].TO) {
    ans[t[x].val] = val;
    return;
  }
  pushdown(x);
  query(t[x].s[0].TO, st * 3, val + st * t[x].s[0].NUM);
  query(t[x].s[1].TO, st * 3, val + st * t[x].s[1].NUM);
  query(t[x].s[2].TO, st * 3, val + st * t[x].s[2].NUM);
}

int main() {
  n = read();
  build(1, 0, 1, 0);
  char c = getchar();
  while (c != 'S' && c != 'R')
    c = getchar();
  while (c == 'S' || c == 'R') {
    if (c == 'S')
      mod2(1);
    else
      mod1(1);
    c = getchar();
  }
  query(1, 1, 0);
  int tmp = 1;
  while (n--)
    tmp *= 3;
  for (int i = 0; i < tmp; i++)
    printf("%d ", ans[i]);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

inline int read() {
  int ret = 0, t = 1;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-')
    c = getchar();
  if (c == '-')
    t = -1, c = getchar();
  while (c >= '0' && c <= '9')
    ret = ret * 10 + c - '0', c = getchar();
  return ret * t;
}

#define PR pair<int, int>
#define MP make_pair
#define TO first
#define NUM second

int n;
const int MAXN = 2002000;
struct tree {
  PR s[3];
  int val;
  bool lazy;
} t[MAXN];
int top = 1;

void build(int x, int st, int tmp, int val) {
  if (st == n) {
    t[x].val = val;
    return;
  }
  t[x].s[0] = MP(++top, 0);
  build(t[x].s[0].TO, st + 1, tmp * 3, val + tmp * 0);
  t[x].s[1] = MP(++top, 1);
  build(t[x].s[1].TO, st + 1, tmp * 3, val + tmp * 1);
  t[x].s[2] = MP(++top, 2);
  build(t[x].s[2].TO, st + 1, tmp * 3, val + tmp * 2);
}

PR fnd(int x) {
  int u, v;
  if (t[x].s[0].NUM == 1)
    u = 0;
  if (t[x].s[1].NUM == 1)
    u = 1;
  if (t[x].s[2].NUM == 1)
    u = 2;
  if (t[x].s[0].NUM == 2)
    v = 0;
  if (t[x].s[1].NUM == 2)
    v = 1;
  if (t[x].s[2].NUM == 2)
    v = 2;
  return MP(u, v);
}

void pushdown(int x) {
  if (!t[x].lazy)
    return;
  t[x].lazy = false;
  for (int i = 0; i < 3; i++) {
    PR tmp = fnd(t[x].s[i].TO);
    int rua = t[x].s[i].TO;
    swap(t[rua].s[tmp.first].NUM, t[rua].s[tmp.second].NUM);
  }
  t[t[x].s[0].TO].lazy ^= 1, t[t[x].s[1].TO].lazy ^= 1,
      t[t[x].s[2].TO].lazy ^= 1;
}

void mod1(int x) {
  if (!t[x].s[0].TO)
    return;
  pushdown(x);
  ++t[x].s[0].NUM, ++t[x].s[1].NUM, ++t[x].s[2].NUM;
  if (t[x].s[0].NUM == 3)
    t[x].s[0].NUM = 0, mod1(t[x].s[0].TO);
  if (t[x].s[1].NUM == 3)
    t[x].s[1].NUM = 0, mod1(t[x].s[1].TO);
  if (t[x].s[2].NUM == 3)
    t[x].s[2].NUM = 0, mod1(t[x].s[2].TO);
}

void mod2(int x) {
  if (!t[x].s[0].TO)
    return;
  PR tmp = fnd(x);
  swap(t[x].s[tmp.first].NUM, t[x].s[tmp.second].NUM);
  t[x].lazy ^= 1;
}

int ans[MAXN];
void query(int x, int st, int val) {
  if (!t[x].s[0].TO) {
    ans[t[x].val] = val;
    return;
  }
  pushdown(x);
  query(t[x].s[0].TO, st * 3, val + st * t[x].s[0].NUM);
  query(t[x].s[1].TO, st * 3, val + st * t[x].s[1].NUM);
  query(t[x].s[2].TO, st * 3, val + st * t[x].s[2].NUM);
}

int main() {
  n = read();
  build(1, 0, 1, 0);
  char c = getchar();
  while (c != 'S' && c != 'R')
    c = getchar();
  while (c == 'S' || c == 'R') {
    if (c == 'S')
      mod2(1);
    else
      mod1(1);
    c = getchar();
  }
  query(1, 1, 0);
  int tmp = 1;
  while (n--)
    tmp *= 3;
  for (int i = 0; i < tmp; i++)
    printf("%d ", ans[i]);
  return 0;
}