Problem:
Score : 1000 points

Problem Statement

There are 3^N people dancing in circle.
We denote with 0,1,\dots, 3^{N}-1 the positions in the circle, starting from an arbitrary position and going around clockwise. Initially each position in the circle is occupied by one person.

The people are going to dance on two kinds of songs: salsa and rumba.

When a salsa is played, the person in position i goes to position j, where j is the number obtained replacing all digits 1 with 2 and all digits 2 with 1 when reading i in base 3 (e.g., the person in position 46 goes to position 65).

When a rumba is played, the person in position i moves to position i+1 (with the identification 3^N = 0).

You are given a string T=T_1T_2\cdots T_{|T|} such that T_i=S if the i-th song is a salsa and T_i=R if it is a rumba.
After all the songs have been played, the person that initially was in position i is in position P_i.
Compute the array P_0,P_1,\dots, P_{3^N-1}.

Constraints

1 \le N \le 12

1 \le |T| \le 200,000

T contains only the characters S and R.

Input

Input is given from Standard Input in the following format:

N
T

Output

You should print on Standard Output:

P_0 P_1 \cdots P_{3^N-1}

Sample Input 1

1
SRS

Sample Output 1

2 0 1

Before any song is played, the positions are: 0, 1, 2.

When we say "person i", we mean "the person that was initially in position i".

After the first salsa, the positions are: 0, 2, 1.

After the rumba, the positions are: 1, 0, 2 (so, person 0 is in position 1, person 1 is in position 0 and person 2 is in position 2).

After the second salsa, the positions are 2, 0, 1 (so, person 0 is in position 2, person 1 is in position 0 and person 2 is in position 1).

Sample Input 2

2
RRSRSSSSR

Sample Output 2

3 8 1 0 5 7 6 2 4

Sample Input 3

3
SRSRRSRRRSRRRR

Sample Output 3

23 9 22 8 3 7 20 24 19 5 18 4 17 12 16 2 6 1 14 0 13 26 21 25 11 15 10

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <string>

#include <cmath>
#include <queue>
#include <stack>

using namespace std;

#define LL long long

const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};

LL mod(LL x, LL md) {
	return ((x % md) + md) % md;
}

class Mint {
public:
	static LL md;
	LL x;
	Mint(LL _x = 0) {
		x = mod(_x, md);
	}
	Mint(const Mint &y) {
		x = mod(y.x, md);
	}
};

void MintMyExgcd(LL a, LL b, LL &x, LL &y) {
	// solve equation ax + by = 1 (mod m)
	LL md = Mint::md;
	if (b == 0) {
		y = 0;
		x = 1;
		return ;
	}
	MintMyExgcd(b, a % b, x, y);
	LL t = y;
	y = mod(x - (a / b) * y, md);
	x = t;
}

LL MintNY(LL x) {
	if (x == 0) {
		return 1;
	}
	LL md = Mint::md;
	LL a, b;
	MintMyExgcd(x, md, a, b);
	while (a < 0) {
		a += md;
	}
	return a;
}

/* LL gcd(LL a, LL b) {
	if (b == 0) {
		return a;
	}
	return gcd(b, a % b);
} */

Mint operator+(Mint a, Mint b) {
	return Mint(mod(a.x + b.x, Mint::md));
}
Mint operator-(Mint a, Mint b) {
	return Mint(mod(a.x - b.x, Mint::md));
}
Mint operator*(Mint a, Mint b) {
	return Mint(mod(a.x * b.x, Mint::md));
}
Mint operator/(Mint a, Mint b) {
	Mint c = Mint(MintNY(b.x));
	return Mint(mod(a.x * c.x, Mint::md));
}

Mint operator-(Mint a) {
	return Mint(-a.x);
}
bool operator==(Mint a, Mint b) {
	return a.x == b.x;
}
bool operator!=(Mint a, Mint b) {
	return a.x != b.x;
}
bool operator>(Mint a, Mint b) {
	return a.x > b.x;
}
bool operator<(Mint a, Mint b) {
	return a.x < b.x;
}
bool operator>=(Mint a, Mint b) {
	return a.x >= b.x;
}
bool operator<=(Mint a, Mint b) {
	return a.x <= b.x;
}

void operator+=(Mint &a, Mint b) {
	a = a + b;
}
void operator-=(Mint &a, Mint b) {
	a = a - b;
}
void operator*=(Mint &a, Mint b) {
	a = a * b;
}
void operator/=(Mint &a, Mint b) {
	a = a / b;
}

ostream& operator<<(ostream &out, Mint a) {
	out << a.x;
	return out;
}

istream& operator>>(istream &in, Mint &a) {
	in >> a.x;
	return in;
}

Mint factorial(LL n) {
	if (n == 0) {
		return Mint(1);
	}
	Mint res = 1;
	for (LL i = 1; i <= n; ++i) {
		res *= i;
	}
	return res;
}
Mint multiRange(LL s, LL t) {
	Mint res = 1;
	for (LL i = s; i <= t; ++i) {
		res *= i;
	}
	return res;
}

Mint getC(LL n, LL k) {
	if (n - k < k) {
		return getC(n, n - k);
	}
	return multiRange(n - k + 1, n) / factorial(k);
}

Mint getA(LL n, LL k) {
	return multiRange(n - k + 1, n);
}

Mint countNonNegativeDivision(LL n, LL k) {
	return getC(n + k - 1, k - 1);
}
Mint countPositiveDivision(LL n, LL k) {
	if (n < k) {
		return 0;
	}
	if (k <= 0) {
		return 0;
	}
	return getC(n - 1, k - 1);
}
Mint quickMod(Mint a, LL b) {
	Mint res = 1;
	while (b > 0) {
		if (b % 2) {
			res *= a;
		}
		a *= a;
		b /= 2;
	}
	return res;
}

int md3 = 1;
int n;

vector<int> toBase3(int x) {
	vector<int> res;
	while (x) {
		res.push_back(x % 3);
		x /= 3;
	}
	return res;
}
int fromBase3(vector<int> &x) {
	int res = 0;
	int base = 1;
	for (int i = 0; i < x.size(); ++i) {
		res += base * x[i];
		base *= 3;
	}
	return res;
}

int flipS(int x) {
	vector<int> b3 = toBase3(x);
	for (int i = 0; i < b3.size(); ++i) {
		b3[i] = (3 - b3[i]) % 3;
	}
	return fromBase3(b3);
}
int flipR(int x) {
	return (x + 1) % md3;
}

LL Mint::md = 1000000007;

vector<int> makeInit() {
	vector<int> a(md3);
	for (int i = 0; i < md3; ++i) {
		a[i] = i;
	}
	return a;
}

void singleFlipS(int &x) {
	x = (3 - x) % 3;
}
void singleFlipR(int &x) {
	x = (x + 1) % 3;
}

void vectorFlipS(vector<int> &a) {
	for (int i = 0; i < a.size(); ++i) {
		a[i] = flipS(a[i]);
	}
}
void vectorFlipR(vector<int> &a) {
	for (int i = 0; i < a.size(); ++i) {
		a[i] = flipR(a[i]);
	}
}
void vectorSingleFlipS(vector<int> &a) {
	for (int i = 0; i < a.size(); ++i) {
		singleFlipS(a[i]);
	}
}
void vectorSingleFlipR(vector<int> &a) {
	for (int i = 0; i < a.size(); ++i) {
		singleFlipR(a[i]);
	}
}

void printVector(vector<int> &a) {
	for (int i = 0; i < a.size(); ++i) {
		cout << a[i] << ' ';
	}
	cout << endl;
}

vector<vector<int> > p, w;
string T;
int t;

void init() {
	p = vector<vector<int> >(n + 1);
	w = vector<vector<int> >(n + 1);
	int base = 1;
	for (int i = 0; i <= n; ++i) {
		w[i] = vector<int>(t + 1);
		p[i] = vector<int>(base);
		base *= 3;
	}

	p[1][0] = 0; p[1][1] = 1; p[1][2] = 2;
	w[1][0] = 2;
	for (int i = 0; i < t; ++i) {
		if (T[i] == 'S') {
			vectorSingleFlipS(p[1]);
		} else {
			vectorSingleFlipR(p[1]);
		}
		for (int j = 0; j < 3; ++j) {
			if (p[1][j] == 2) {
				w[1][i + 1] = j;
				break;
			}
		}
	}
}

vector<int> upt;
vector<int> sSum;

void relax(int order, int idx, int nowTime) {
	int sTime = sSum[nowTime] - sSum[upt[idx]];
	if (sTime % 2) {
		p[order][idx] = (3 - p[order][idx]) % 3;
	}
	upt[idx] = nowTime;
}

void work() {
	sSum = vector<int>(t + 1);
	sSum[0] = 0;
	for (int i = 1; i <= t; ++i) {
		sSum[i] = sSum[i - 1] + ((T[i - 1] == 'S') ? 1 : 0);
	}
	int base = 3;
	for (int i = 2; i <= n; ++i) {
		upt = vector<int>(p[i].size(), 0);
		// get p[i][j = 1 .. 3^i], w[i][1 .. T]
		// if we have already gotten p[i][j = 1 .. 3^i]

		for (int j = 0; j < p[i].size(); ++j) {
			p[i][j] = j / base;
		}
		w[i][0] = 2;

		for (int j = 0; j < t; ++j) {
			if (T[j] == 'R') {
				for (int ii = 0; ii < 3; ++ii) {
					int idx = ii * base + w[i - 1][j];
					relax(i, idx, j);
					p[i][idx] = (p[i][idx] + 1) % 3;
					upt[idx] += 1;
				}
				for (int ii = 0; ii < 3; ++ii) {
					int idx = ii * base + w[i - 1][j + 1];
					relax(i, idx, j);
					if (p[i][idx] == 2) {
						w[i][j + 1] = ii;
						break;					
					}
				}
			} else {
				// for (int ii = 0; ii < p[i].size(); ++ii) {
				// 	p[i][ii] = (3 - p[i][ii]) % 3;
				// }
				for (int ii = 0; ii < 3; ++ii) {
					int idx = ii * base + w[i - 1][j + 1];
					relax(i, idx, j); 
					p[i][idx] = (3 - p[i][idx]) % 3;
					upt[idx] += 1;
					if (p[i][idx] == 2) {
						w[i][j + 1] = ii;	
						break;				
					}
				}
			}
		}

		for (int j = 0; j <= t; ++j) {
			w[i][j] = w[i][j] * base + w[i - 1][j];
		}
		for (int j = 0; j < p[i].size(); ++j) {
			relax(i, j, t);
			p[i][j] = p[i][j] * base + p[i - 1][j % base];
		}
		base *= 3;

		// cout << "w: ";
		// for (int j = 0; j <= t; ++j) {
		// 	cout << w[i][j] << ' ';
		// }
		// cout << endl;
		
		// cout << "p: ";
		// for (int j = 0; j < p[i].size(); ++j) {
		// 	cout << p[i][j] << ' ';
		// }
		// cout << endl;
	}
	for (int i = 0; i < p[n].size(); ++i) {
		printf("%d ", p[n][i]);
	}
	putchar('\n');
}

int main() {
	scanf("%d", &n);
	cin >> T;
	// cout << T << endl;
	t = T.length();
	md3 = 1;
	for (int i = 0; i < n; ++i) {
		md3 *= 3;
	}

	init();
	work();

	// vector<int> a1 = makeInit();
	// vector<int> a2 = makeInit();
	// vectorFlipS(a1); vectorFlipR(a1);
	// vectorFlipR(a2); vectorFlipS(a2);

	// printVector(a1);
	// printVector(a2);
	
	return 0;
}