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

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

int pow(int a, int n) {
  if (n <= 0)
    return 0;
  if (n == 1)
    return a;
  return (pow(a, n - 1) * a);
}

int tri_rev(int t, int n) {
  if (t / n == 0)
    return t;
  int x = (t % (n * 3)) / n;
  int y = (x == 1) ? 2 : ((x == 2) ? 1 : 0);
  return tri_rev(t - x * n + y * n, n * 3);
}

void readRS(const char *p, vector<int> &RS) {
  RS.clear();
  int sw = 0;
  int c = 1;
  bool f = true;
  while (f) { // R = 82 = 平行移動, S = 83 = 3置換
    if (*p == sw) {
      c++;
    } else {
      if (sw == 83) {
        if (c % 2 == 1) {
          RS.push_back(-1);
        }
      } else if (sw == 82) {
        for (int i = 0; i < c; i++) {
          RS.push_back(1);
        }
      }
      c = 1;
      sw = *p;
    }
    if (*p == '\\0')
      break;
    p++;
  }
}

int main() {
  int N;
  cin >> N;

  // readRS
  string s;
  cin >> s;
  vector<int> RS(200001, 0); // 1 = 平行移動, -1 = 3置換
  readRS(s.c_str(), RS);

  // swap set	作成
  vector<int> SW(pow(3, N), 0);
  for (int i = 0; i < pow(3, N); i++) {
    if (SW[i] == 0) {
      int j = tri_rev(i, 1);
      SW[i] = j;
      SW[j] = i;
    }
  }

  vector<int> P0(1, 0); // 前のlvの到達点を入れる。P0[i] =
                        // iの最終到達点。初期値はlv=0で、P0[0]=0のみ。
  vector<int> W0(
      RS.size() + 1,
      0); // RSの各点に置いて、最後の座席に座っている人のIDを取っておく。lv =
          // 0ならばW0[k] = 0 for all k W0[0] =
          // 一度もRSをしていない状態での、最後の席の人のID = 3^lv -1
          // W0[RS.size()-1] = 最後のRSをする直前の、最後の座席の人のID
  for (int lv = 1; lv <= N; lv++) {
    // 初期化
    // 3^lv の世界を作る
    int M = pow(3, lv);   // 座席数＝人数
    int m = M / 3;        // 一つ前のlvのm
    vector<int> P1(M, 0); // 最終到達点を入れる
    vector<int> W1(RS.size() + 1,
                   0); // k回目の操作のあとに最終座席にいる人のIDを入れる。
    map<int, int> D0, D1,
        D2; // 全員の最大digitを入れて、k回の操作で更新していく。Dxに入っているidは、最大digitがx

    // D初期値
    for (int i = 0; i < m; i++) {
      D0.insert(pair<int, int>(i, i));
      D1.insert(pair<int, int>(i, i + m));
      D2.insert(pair<int, int>(i, i + 2 * m));
    }

    // D更新, W1記録
    W1[0] = M - 1;
    for (int k = 0; k < RS.size(); k++) {
      // Dの更新
      if (RS[k] == -1) {
        // 3置換: Dは1 -> 2, 2 -> 1
        D1.swap(D2);
      } else {
        // 平行移動 繰り上がりだけ処理する。
        int i = D2[W0[k]];
        D2[W0[k]] = D1[W0[k]];
        D1[W0[k]] = D0[W0[k]];
        D0[W0[k]] = i;
      }
      // W1[k+1] の作成。W1[k+1]は、2,W0[k+1]の人。
      W1[k + 1] = D2[W0[k + 1]];
    }
    // 最後まで到達した
    for (auto it = D0.begin(); it != D0.end(); it++) {
      P1[it->second] = P0[it->first];
    }
    for (auto it = D1.begin(); it != D1.end(); it++) {
      P1[it->second] = P0[it->first] + m;
    }
    for (auto it = D2.begin(); it != D2.end(); it++) {
      P1[it->second] = P0[it->first] + 2 * m;
    }

    // 次のレベルへ
    P0.swap(P1);
    W0.swap(W1);
  }

  // out
  for (int i = 0; i < pow(3, N); i++) {
    cout << P0[i] << " ";
  }
  cout << endl;
  return (0);
}


Error: TLE

Fixed submission:

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

int pow(int b, int e) {
  if (e == 1) {
    return b;
  } else {
    return (pow(b, e - 1) * b);
  }
}

int trt(int t, int n) {
  if (t / n == 0)
    return t;
  int x = (t % (n * 3)) / n;
  int y = (x == 1) ? 2 : ((x == 2) ? 1 : 0);
  return trt(t - x * n + y * n, n * 3);
}

int main() {
  int N;
  cin >> N;
  int M = pow(3, N);
  queue<int> RS;
  char *s = new char[200001];
  cin >> s;
  char *p = s;
  int sw = 0;
  int c = 1;
  bool f = true;
  while (f) { // R = 82 = 平行移動, S = 83 = 3置換
    if (*p == sw) {
      c++;
    } else {
      if (sw == 83) {
        if (c % 2 == 1) {
          RS.push(-1);
        }
      } else if (sw == 82) {
        RS.push(c);
      }
      c = 1;
      sw = *p;
    }
    if (*p == '\\0')
      break;
    p++;
  }

  vector<int> A(M, 0); // current status
  for (int i = 0; i < M; i++)
    A[i] = i;
  deque<pair<int, int>> P; // 置換index

  // swap set	作成
  vector<int> W(M, 0);
  for (int i = 0; i < M; i++) {
    if (W[i] == 0) {
      int j = trt(i, 1);
      W[i] = j;
      W[j] = i;
      P.push_back(pair<int, int>(i, j));
    }
  }
  //	for (auto it = P.begin(); it != P.end(); it++) {
  //		cout << "P:" << it->first << "," << it->second << endl;
  //	}

  // calc
  int x = 0; // 0位置を示す
             //	for (int i = 0; i < M; i++) {
             //		cout << A[(i + x) % M] << " ";
             //	}
             //	cout << endl;
  while (!RS.empty()) {
    int rs = RS.front();
    RS.pop();
    if (rs == -1) {
      // 置換
      for (auto it = P.begin(); it != P.end(); it++) {
        swap(A[(x + it->first) % M], A[(x + it->second) % M]);
      }
    } else {
      x = (((x - rs) % M) + M) % M;
    }
    // out
    //		cout << rs << ": ";
    //		for (int i = 0; i < M; i++) {
    //			cout << A[(i + x) % M] << " ";
    //		}
    //		cout << endl;
  }

  // out
  vector<int> B(
      M, 0); // A[i] = i番目のセルにいる人の名前 -> B[i] = iさんがB[i]にいる
  for (int i = 0; i < M; i++) {
    B[A[(i + x) % M]] = i;
  }
  for (int i = 0; i < M; i++) {
    cout << B[i] << " ";
  }
  cout << endl;
  return (0);
}