Problem:
古代遺跡の謎
古代遺跡から超大型あみだくじが発見された。学者達はこれをVLA(Very Long Amidakuji)と命名した。分析の結果、VLAは
N
本の縦棒を持ついくつかの部品の組み合わせで構成され、多くの場合繰り返しを含んでいることがわかった。例えば、図のVLAは２種類の部品AとBを使った４つの部品から構成されている。
このVLAの上端に左から順番に 1,2,3,4,5 と番号をつけ、それぞれの番号からVLAをたどり（あみだくじのたどり方については問題文最後の補足を参照してください)、下端にたどり着いた場所の縦棒にその番号を振る。すべての番号についてたどり終えた後で、下端に振られた番号を左から読むと 4,2,5,1,3 になる。このように、1,2,3,4,5 という番号の列が 4,2,5,1,3 という列に変換される。
彼らはVLAによって 1 から
N
までの番号の列がどのように変換されるのかを知りたいが、手作業でたどるのは大変そうだ。そこでパソコン甲子園出場者である優秀なプログラマーの君たちに、VLAのシミュレーションを依頼した。
VLAはとても長いため、そのままの状態ではプログラマーたちに情報を伝えることができない。そこで学者たちは、部品の種類を英大文字１つで表し、VLAを式で表現することにした。
部品は同じ位置関係である縦棒が一致するように、左から順番に
+
演算子で接続される。たとえば、上からA,B,C,D という順番で連結された部品の列は
A+B+C+D
という式で表記される。
部品の列を表す式
seq
の
m
回の繰り返しは、
m
(
seq
) と表記できる。たとえば、
A+B
の2回の繰り返しは
2(A+B)
と表せ、これは
A+B+A+B
と同じである。また、
seq
が１つの部品
a
の場合は、
a
を囲むかっこを省略しても構わない。
4(A+B)
と
3(X+Y)
を、この順番で連結したVLAは
4(A+B)+3(X+Y)
と表せる。また、かっこは
2(4(A+B)+3(X+Y))+10C
のように入れ子にしても構わない。
それでは、縦棒の数
N
、各部品の情報、複数のVLAの式を入力とし、各式が表すVLAによって1から
N
までの番号の列がどのように変換されるかを出力するプログラムを作成しなさい。
（※補足：あみだくじのたどり方について）
あみだくじのある縦棒の上端から出発して上から下へ進む。ただし、横棒がある地点ではその横棒でつながった別の縦棒に移動する。これを、縦棒の下端にたどり着くまで繰り返す。
入力
入力は１つのデータセットからなる。入力データは以下の形式で与えられる。
N
K
p
1
h
1
g
1
(1,1)
g
1
(1,2) ..
g
1
(1,
N
-1)
g
1
(2,1)
g
1
(2,2) ..
g
1
(2,
N
-1)
:
g
1
(
h
1
-1,1)
g
1
(
h
1
-1,2) ..
g
1
(
h
1
-1,
N
-1)
p
2
h
2
g
2
(1,1)
g
2
(1,2) ..
g
2
(1,
N
-1)
g
2
(2,1)
g
2
(2,2) ..
g
2
(2,
N
-1)
:
g
2
(
h
2
-1,1)
g
2
(
h
2
-1,2) ..
g
2
(
h
2
-1,
N
-1)
:
p
K
h
K
g
K
(1,1)
g
K
(1,2) ..
g
K
(1,
N
-1)
g
K
(2,1)
g
K
(2,2) ..
g
K
(2,
N
-1)
:
g
K
(
h
K
-1,1)
g
K
(
h
K
-1,2) ..
g
K
(
h
K
-1,
N
-1)
E
expression
1
expression
2
:
expression
E
1行目に縦棒の数を表す整数
N
(2 ≤
N
≤ 12) と部品の種類の数
K
(1 ≤
K
≤ 26)が与えられる。
2行目以降に
K
種類の部品の情報が与えられる。各部品は以下の形式で与えられる。
最初の行は部品名を表す１つの英大文字
p
i
と部品
i
の縦棒の長さを表す整数
h
i
(1 ≤
h
i
≤ 20)を含む。
続く
h
i
-1 行で部品
i
の横棒の情報が与えられる。
g
i
(
r, c
) は部品
i
の上端から長さ
r
の位置において、左から
c
番目の縦棒と
c
+1 番目の縦棒をつなぐ横棒の有無を表す。横棒があるときは
g
i
(
r
,
c
) = 1、横棒がないときは
g
i
(
r
,
c
) = 0である。
続く１行に式の数
E
(1 ≤
E
≤ 100) が与えられる。続く
E
行にVLAの式を表す文字列 expression
i
（1文字以上1000文字以下）が与えられる。
入力は以下の条件を満たす。
異なる部品に同じ名前が使われることはない。
各部品
i
について、
g
i
(
r
,
c
)と
g
i
(
r
,
c
+1)が同時に 1 となることはない。
式に含まれる整数は 1 以上 1,000,000,000 以下である。
式には空白は含まれない。
出力
式ごとに、VLAによる1からNまでの列の変換結果を１行に出力する。それぞれの数字の間は空白1つで区切る。
入出力例
入力例
5 2
A 5
1 0 0 1
0 1 0 0
1 0 1 0
0 1 0 1
B 4
1 0 0 1
0 1 0 0
0 0 1 0
2
2(A+B)
1000000000(1000000000A+1000000000B)
出力例
4 2 5 1 3
1 2 3 4 5

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <string>
using namespace std;

int H, N, Q, p[30][30]; vector<int>r[30], J; string c[30]; string S;

vector<int>amida_add(vector<int>a, vector<int>b) {
	vector<int>c = a, p = a, q = a;
	for (int i = 0; i < a.size(); i++)p[a[i]] = i;
	for (int i = 0; i < b.size(); i++)q[b[i]] = i;
	for (int i = 0; i < a.size(); i++)c[q[p[i]]] = i;
	return c;
}

vector<int> amida_rep(vector<int>a, int rep) {
	vector<int>dp[32], res = J;
	for (int i = 0; i < 32; i++) { dp[i].resize(a.size(), 0); }
	dp[0] = a;
	for (int i = 0; i < 31; i++) dp[i + 1] = amida_add(dp[i], dp[i]);
	for (int i = 0; i < 31; i++) {
		if ((rep / (1 << i)) % 2 == 1) res = amida_add(res, dp[i]);
	}
	return res;
}

vector<int>solve(int L, int R) {
	if (L == R) {
		for (int i = 0; i < N; i++) { if (S[L] == c[i][0])return r[i]; }
	}
	vector<int>D; D.push_back(L - 1); int depth = 0;
	for (int i = L; i <= R; i++) { if (S[i] == '(')depth++; if (S[i] == ')')depth--; if (S[i] == '+' && depth == 0) D.push_back(i); } D.push_back(R + 1);
	if (D.size() >= 3) {
		vector<int> T = J;
		for (int i = 0; i < D.size() - 1; i++) { vector<int>U = solve(D[i] + 1, D[i + 1] - 1); T = amida_add(T, U); }
		return T;
	}
	int cl = -1, cr = -1;
	for (int i = L; i <= R; i++) { if (S[i] == '(') { cl = i; break; } }
	for (int i = R; i >= L; i--) { if (S[i] == ')') { cr = i; break; } }
	if (cl != -1) {
		int P = stoi(S.substr(L, cl - L));
		vector<int>U = solve(cl + 1, cr - 1);
		U = amida_rep(U, P);
		return U;
	}
	int PP = stoi(S.substr(L, R - L));
	vector<int>UU = solve(R, R);
	UU = amida_rep(UU, PP);
	return UU;
}

int main() {
	cin >> H >> N;
	for (int j = 0; j < H; j++) J.push_back(j);
	for (int i = 0; i < N; i++) {
		int w = 0; cin >> c[i] >> w; r[i] = J;
		for (int j = 0; j < w - 1; j++) {
			for (int k = 0; k < H - 1; k++) {
				cin >> p[j][k]; if (p[j][k] == 1) swap(r[i][k], r[i][k + 1]);
			}
		}
	}
	cin >> Q;
	for (int i = 0; i < Q; i++) {
		cin >> S;
		vector<int>ans = solve(0, S.size() - 1);
		for (int j = 0; j < ans.size(); j++) { if (j)cout << " "; cout << ans[j] + 1; }cout << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3408
final_rank: 10

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <atcoder/all>
// #include "qitoy/math/binomial.hpp"

#define rep(i, n) for (long long i = 0; i < (n); i++)
#define rep1(i, n) for (long long i = 1; i <= (n); i++)
#define all(v) v.begin(), v.end()
#define decimal(n) cout << fixed << setprecision(n);
using namespace std;
// using namespace atcoder;
using vi = vector<int>; using vvi = vector<vi>; using vs = vector<string>;
using ll = long long; using vl = vector<ll>; using vvl = vector<vl>; 
// using mint = modint998244353;
// const ll MOD = 998244353;
// using mint = modint;
// const ll MOD = 998244353;
// using mint = modint1000000007;
// const ll MOD = 1000000007;
// using vm = vector<mint>; using vvm = vector<vm>;
using vll = vl;
using P = pair<ll, ll>; using T = tuple<ll, ll, ll>;
using vc = vector<char>; using vvc = vector<vc>;
const ll MAX = 2000100; const ll llINF = 2e18;
const int intINF = 2e9; const long double pi = acos(-1);
ll di[] = {0, -1, 0, 1, -1, -1, 1, 1};
ll dj[] = {1, 0, -1, 0, 1, -1, -1, 1};
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

#include <string>
#include <cctype>
typedef string::const_iterator State;
class ParseError {};

vvl amida;
// プロトタイプ宣言
vl expression(State &begin);
vl terms(State &begin);
vl factor(State &begin);
vl element(State &begin);
ll number(State &begin);
vl sum(vl a, vl b);
void consume(State &begin, char expected);

ll n;

// 四則演算の式をパースして、その評価結果を返す。
vl expression(State &begin) {
    vl ret(n);
    iota(all(ret), 1ll);
    ret = sum(ret, terms(begin));
    while(true) {
        if(*begin == '+') {
            consume(begin, '+');
            ret = sum(ret, terms(begin));
        }
        else break;
    }
    return ret;
}

vl terms(State &begin) {
    ll time = 1;
    vl ret;
    iota(all(ret), 1ll);
    if(isdigit(*begin)) {
        time = number(begin);
    }
    ret = factor(begin);

    vl ans(n);
    iota(all(ans), 1ll);
    for(ll i = 0; i <= 31; i++) {
        if(time & (1ll << i)) {
            ans = sum(ans, ret);
        }
        ret = sum(ret, ret);
    }
    ret = ans;

    return ret;
}

vl factor(State &begin) {
    vl ret;
    iota(all(ret), 1ll);
    if(*begin != '(') {
        ret = element(begin);
    }
    else if(*begin == '(') {
        consume(begin, '(');
        ret = expression(begin);
        consume(begin, ')');
    }
    return ret;
}

vl element(State &begin) {
    vl ret = amida[*begin - 'A'];
    begin++;
    return ret;
}

// 数字の列をパースして、その数を返す。
ll number(State &begin) {
    ll ret = 0;

    while (isdigit(*begin)) {
        ret *= 10;
        ret += *begin - '0';
        begin++;
    }

    return ret;
}

// aからbへのamidaの結合
vl sum(vl a, vl b) {
    vl next(n);
    rep(i, n) {
        next[i] = a[b[i] - 1];
    }
    return next;
}

// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
    if (*begin == expected) {
        begin++;
    } else {
        cerr << "Expected '" << expected << "' but got '" << *begin << "'"
            << endl;
        cerr << "Rest string is '";
        while (*begin) {
            cerr << *begin++;
        }
        cerr << "'" << endl;
        throw ParseError();
    }
}

int main() {
    ll k;
    cin >> n >> k;
    amida.resize(26);
    rep(ii, k) {
        char c; ll v;
        cin >> c >> v;
        vl num(n);
        iota(all(num), 1LL);
        rep(hh, v - 1) {
            rep(i, n - 1) {
                ll x;
                cin >> x;
                if(x == 1) {
                    swap(num[i], num[i + 1]);
                }
            }
        }
        amida[c - 'A'] = num;
    }
    ll e;
    cin >> e;
    while(e--) {
        string s;
        cin >> s;
        State begin = s.begin();
        vl ans = expression(begin);
        assert(s.end() == begin);
        rep(i, n) {
            cout << ans[i] << (i == n - 1 ? "" : " ");
        }
        cout << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3456
final_rank: 14

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <atcoder/all>
// #include "qitoy/math/binomial.hpp"

#define rep(i, n) for (long long i = 0; i < (n); i++)
#define rep1(i, n) for (long long i = 1; i <= (n); i++)
#define all(v) v.begin(), v.end()
#define decimal(n) cout << fixed << setprecision(n);
using namespace std;
// using namespace atcoder;
using vi = vector<int>; using vvi = vector<vi>; using vs = vector<string>;
using ll = long long; using vl = vector<ll>; using vvl = vector<vl>; 
// using mint = modint998244353;
// const ll MOD = 998244353;
// using mint = modint;
// const ll MOD = 998244353;
// using mint = modint1000000007;
// const ll MOD = 1000000007;
// using vm = vector<mint>; using vvm = vector<vm>;
using vll = vl;
using P = pair<ll, ll>; using T = tuple<ll, ll, ll>;
using vc = vector<char>; using vvc = vector<vc>;
const ll MAX = 2000100; const ll llINF = 2e18;
const int intINF = 2e9; const long double pi = acos(-1);
ll di[] = {0, -1, 0, 1, -1, -1, 1, 1};
ll dj[] = {1, 0, -1, 0, 1, -1, -1, 1};
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

#include <string>
#include <cctype>
typedef string::const_iterator State;
class ParseError {};

vvl amida;
// プロトタイプ宣言
vl expression(State &begin);
vl factor(State &begin);
vl element(State &begin);
ll number(State &begin);
vl sum(vl a, vl b);
void consume(State &begin, char expected);

ll n;

// 四則演算の式をパースして、その評価結果を返す。
vl expression(State &begin) {
    vl ret(n);
    iota(all(ret), 1ll);
    ret = sum(ret, factor(begin));
    while(true) {
        if(*begin == '+') {
            consume(begin, '+');
            ret = sum(ret, factor(begin));
        }
        else break;
    }
    return ret;
}

vl factor(State &begin) {
    ll time = 1;
    vl ret;
    iota(all(ret), 1ll);
    if(isdigit(*begin)) {
        time = number(begin);
    }

    if(*begin != '(') {
        ret = element(begin);
    }
    else if(*begin == '(') {
        consume(begin, '(');
        ret = expression(begin);
        consume(begin, ')');
    }
    vl ans(n);
    iota(all(ans), 1ll);
    for(ll i = 0; i <= 31; i++) {
        if(time & (1ll << i)) {
            ans = sum(ans, ret);
        }
        ret = sum(ret, ret);
    }
    ret = ans;

    return ret;

}

vl element(State &begin) {
    vl ret = amida[*begin - 'A'];
    begin++;
    return ret;
}

// 数字の列をパースして、その数を返す。
ll number(State &begin) {
    ll ret = 0;

    while (isdigit(*begin)) {
        ret *= 10;
        ret += *begin - '0';
        begin++;
    }

    return ret;
}

// aからbへのamidaの結合
vl sum(vl a, vl b) {
    vl next(n);
    rep(i, n) {
        next[i] = a[b[i] - 1];
    }
    return next;
}

// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
    if (*begin == expected) {
        begin++;
    } else {
        cerr << "Expected '" << expected << "' but got '" << *begin << "'"
            << endl;
        cerr << "Rest string is '";
        while (*begin) {
            cerr << *begin++;
        }
        cerr << "'" << endl;
        throw ParseError();
    }
}

int main() {
    ll k;
    cin >> n >> k;
    amida.resize(26);
    rep(ii, k) {
        char c; ll v;
        cin >> c >> v;
        vl num(n);
        iota(all(num), 1LL);
        rep(hh, v - 1) {
            rep(i, n - 1) {
                ll x;
                cin >> x;
                if(x == 1) {
                    swap(num[i], num[i + 1]);
                }
            }
        }
        amida[c - 'A'] = num;
    }
    ll e;
    cin >> e;
    while(e--) {
        string s;
        cin >> s;
        State begin = s.begin();
        vl ans = expression(begin);
        assert(s.end() == begin);
        rep(i, n) {
            cout << ans[i] << (i == n - 1 ? "" : " ");
        }
        cout << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3372
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef string::const_iterator State;
class ParseError {};

vector<int> pattern(State &begin);
int number(State &begin);
vector<int> term(State &begin);
vector<int> expression(State &begin);
vector<int> factor(State &begin);
map<char, vector<int>> order;
int n;
vector<int> composition(vector<int> &a, vector<int> ord){
    vector<int> ret(n);
    for(int i=0;i<n;i++){
        ret[i] = ord[a[i]];
    }
    return ret;
}
vector<int> mul(vector<int> ord, int num){
    if(num == 1) return ord;
    if(num % 2 == 0){
        vector<int> elem = mul(ord, num/2);
        return composition(elem, elem);
    }
    return composition(ord, mul(ord, num-1));
}
int number(State &begin){
    int ret = 0;
    while(isdigit(*begin)){
        ret = 10*ret + (*begin - '0');
        begin++;
    }
    return ret;
}
vector<int> term(State &begin){
    if(isdigit(*begin)){
        int num = number(begin);
        vector<int> ret = mul(factor(begin), num);
        return ret;
    }
    else{
        return factor(begin);
    }
}
vector<int> expression(State &begin){
    vector<int> ret = term(begin);
    while(true){
        if(*begin == '+'){
            begin++;
            ret = composition(ret, term(begin));
        }
        else{
            break;
        }
    }
    return ret;
}
vector<int> factor(State &begin){
    if(*begin == '('){
        begin++;
        vector<int> ret = expression(begin);
        begin++;
        return ret;
    }
    else{
        vector<int> ret = order[*begin];
        begin++;
        return ret;
    }

}

void solve(){
    string s;
    // getline(cin, s);
    cin >> s;
    s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
    State begin = s.begin();
    vector<int> ord = expression(begin);
    vector<int> ans(n);
    for(int i=0;i<n;i++) ans[ord[i]] = i;

    for(int i=0;i<n-1;i++) cout << ans[i] + 1<< " ";
    cout << ans.back() + 1<< endl;
}

vector<int> make_order(vector<vector<int>> &g){
    int h = g.size();
    vector<int> ret(n);
    for(int i=0; i<n; i++){
        int now = i;
        for(int j=0;j<h;j++){
            if(now > 0 && g[j][now-1]){
                now--;
            } 
            else if(now < n-1 && g[j][now]){
                now++;
            }
        }        
        ret[i] = now;
    }
    return ret;
}

int main(){
    int k;
    cin >> n >> k;
    for(int i=0; i<k; i++){
        char c;
        int h;
        cin >> c >> h;
        vector<vector<int>> g(h-1,vector<int>(n-1));
        for(int j=0; j<h-1; j++){
            for(int l=0; l<n-1; l++){
                cin >> g[j][l];
            }
        }
        order[c] = make_order(g);
    }
    int q; 
    cin >> q;
    while(q--){
        solve();
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3452
final_rank: 13

code_snippet: #include <bits/stdc++.h>

struct Data {
    static constexpr int LOG = 30;
    std::vector<std::vector<int>> doubling;

    Data() = default;
    Data(const std::vector<int>& perm) {
        int n = perm.size();
        doubling.resize(LOG + 1, std::vector<int>(n));
        std::copy(perm.begin(), perm.end(), doubling.front().begin());
        for (int i = 0; i < LOG; i++) {
            for (int j = 0; j < n; j++) {
                doubling[i + 1][j] = doubling[i][doubling[i][j]];
            }
        }
    }

    int operator[](int i) const {
        return doubling[0][i];
    }

    Data repeat(int n) {
        std::vector<int> result;
        for (int i = 0; i < (int)doubling.front().size(); i++) {
            int rem = n;
            int u = i;
            for (int j = 0; j <= LOG; j++) {
                if (rem & 1) {
                    u = doubling[j][u];
                }
                rem >>= 1;
            }
            result.push_back(u);
        }
        return Data(result);
    }

    friend Data operator+(const Data& lhs, const Data& rhs) {
        std::vector<int> result(lhs.doubling.front().size());
        for (int i = 0; i < (int)lhs.doubling.front().size(); i++) {
            result[i] = lhs[rhs[i]];
        }
        return Data(result);
    }

    static void test() {
        Data a({0, 3, 2, 1});
        Data b({1, 2, 0, 3});
        Data c = a + b;
        for (int i = 0; i < 4; i++) {
            std::cout << c.doubling[0][i] << std::endl;
        }
    }
};

std::ostream& operator<<(std::ostream& os, const Data& data) {
    for (int i = 0; i < (int)data.doubling.front().size(); i++) {
        os << data[i] + 1;
        if (i + 1 < (int)data.doubling.front().size()) {
            os << ' ';
        }
    }
    return os;
}

Data to_data(const std::vector<std::vector<int>>& vla) {
    std::vector<int> res(vla.front().size() + 1);
    std::iota(res.begin(), res.end(), 0);

    for (int i = (int)vla.size() - 1; i >= 0; i--) {
        for (int j = 0; j < (int)vla.front().size(); j++) {
            if (vla[i][j] == 1) {
                std::swap(res[j], res[j + 1]);
            }
        }
    }

    auto temp = res;
    for (int i = 0; i < (int)res.size(); i++) {
        res[temp[i]] = i;
    }

    return Data(res);
}

std::array<Data, 256> database;

class ParseError {};

struct Parser {
    std::string s;
    using Iter = std::string::const_iterator&;

    Parser(std::string s): s(s) {}

    void consume(Iter it, char c) {
        it++;
    }

    Data parse() {
        auto it = s.cbegin();
        return expr(it);
    }

    Data expr(Iter it) {
        auto res = term(it);
        while (it != s.end() && *it == '+') {
            consume(it, '+');
            res = res + term(it);
        }
        return res;
    }

    Data term(Iter it) {
        int rep = number(it);
        if (*it == '(') {
            consume(it, '(');
            auto data = expr(it);
            consume(it, ')');
            return data.repeat(rep);
        } else {
            auto data = database[*it];
            it++;
            return data.repeat(rep);
        }
    }

    int number(Iter it) {
        int res = 0;
        while (it != s.end() && std::isdigit(*it)) {
            res = 10 * res + (*it) - '0';
            it++;
        }
        if (res == 0) res = 1;
        return res;
    }
};

int main() {
    int n, k;
    std::cin >> n >> k;
    for (int i = 0; i < k; i++) {
        char p;
        int h;
        std::cin >> p >> h;
        std::vector<std::vector<int>> vla(h - 1, std::vector<int>(n - 1));
        for (int j = 0; j + 1 < h; j++) {
            for (int l = 0; l + 1 < n; l++) {
                std::cin >> vla[j][l];
            }
        }
        Data data = to_data(vla);

        database[p] = data;
    }

    int e;
    std::cin >> e;
    std::cin.ignore();
    while (e--) {
        std::string s;
        std::getline(std::cin, s);
        Parser parser(s);
        auto data = parser.parse();
        std::cout << data << std::endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3476
final_rank: 15

code_snippet: /*
 * 0291.cc: Mystery of an Ancient Ruin
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 12;
const int MAX_K = 26;
const int MAX_L = 1000;

/* typedef */

typedef vector<int> vi;

struct Amida {
  static int n;
  vi ds;
  Amida() {
    ds.resize(n);
    for (int i = 0; i < n; i++) ds[i] = i;
  }

  Amida operator+(const Amida &a) const {
    Amida r;
    for (int i = 0; i < n; i++) r.ds[i] = ds[a.ds[i]];
    return r;
  }

  Amida operator*(int m) {
    Amida p, a = *this;
    while (m > 0) {
      if (m & 1) p = p + a;
      a = a + a;
      m >>= 1;
    }
    return p;
  }

  void print() {
    for (int i = 0; i < n; i++)
      printf("%d%c", ds[i] + 1, (i + 1 < n) ? ' ' : '\n');
  }
};
int Amida::n;

/* global variables */

Amida as[MAX_K];
char s[MAX_L + 4];

/* subroutines */

Amida expr(char *(&cpt));

Amida elm(char *(&cpt)) {
  if (*cpt == '(') {
    cpt++; // '(';
    Amida e = expr(cpt);
    cpt++; // ')';
    return e;
  }

  Amida e = as[*(cpt++) - 'A'];
  return e;
}

Amida term(char *(&cpt)) {
  int c = 1;
  if (*cpt >= '0' && *cpt <= '9') {
    c = 0;
    while (*cpt >= '0' && *cpt <= '9')
      c = c * 10 + (*(cpt++) - '0');
  }

  Amida e = elm(cpt);
  return (c > 1) ? e * c : e;
}

Amida expr(char *(&cpt)) {
  Amida t0 = term(cpt);
  while (*cpt == '+') {
    cpt++; // '+'
    Amida t1 = term(cpt);
    t0 = t0 + t1;
  }
  return t0;
}

/* main */

int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  Amida::n = n;

  for (int i = 0; i < k; i++) {
    char cs[4];
    int hi;
    scanf("%s%d", cs, &hi);

    Amida ai;
    //ai.print();
    for (int y = 0; y + 1 < hi; y++) {
      for (int x = 0; x + 1 < n; x++) {
	int gx;
	scanf("%d", &gx);
	if (gx) swap(ai.ds[x], ai.ds[x + 1]);
      }
      //ai.print();
    }
    as[cs[0] - 'A'] = ai;
    //printf("%c = ", cs[0]); ai.print();
  }

  int qn;
  scanf("%d", &qn);

  while (qn--) {
    scanf("%s", s);
    char *cpt = s;
    Amida e = expr(cpt);
    e.print();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2968
final_rank: 2

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

using ll = long long;

typedef string::const_iterator State;
class ParseError {};

int n;

struct Part {
    vector<int> p;  // {0, 1, ... n-1} がそれぞれどこに行くか
    Part(vector<vector<int>> field) {
        p.resize(n);
        iota(p.begin(), p.end(), 0);
        for(auto&& v : field) {
            for(int i = 0; i < n - 1; i++) {
                if(v[i] == 1) swap(p[i], p[i + 1]);
            }
        }
    }
    Part() {
        p.resize(n);
        iota(p.begin(), p.end(), 0);
    }
};

Part parts[256];

Part add(const Part& l, const Part& r) {
    Part ret;
    for(int i = 0; i < n; i++) {
        ret.p[i] = l.p[r.p[i]];
    }
    return ret;
}

Part mul(int x, Part p) {
    Part ret;
    while(x) {
        if(x & 1) ret = add(ret, p);
        p = add(p, p);
        x /= 2;
    }
    return ret;
}

int number(State& ptr) {
    int ret = 0;
    while(isdigit(*ptr)) {
        ret *= 10;
        ret += *ptr - '0';
        ptr++;
    }
    return ret;
}

Part tasu(State&);

Part kake(State& ptr) {
    // cout << "kake " << *ptr << endl;
    int num = max(number(ptr), 1);
    Part ret;
    if(*ptr == '(') {
        ptr++;
        ret = tasu(ptr);
        ptr++;
    } else {
        ret = parts[*ptr];
        ptr++;
    }
    return mul(num, ret);
}

Part tasu(State& ptr) {
    // cout << "tasu " << *ptr << endl;
    Part ret = kake(ptr);
    while(*ptr == '+') {
        ptr++;
        ret = add(ret, kake(ptr));
    }
    return ret;
}

int main() {
    int k;
    cin >> n >> k;
    for(int i = 0; i < k; i++) {
        char c;
        int h;
        cin >> c >> h;
        vector field(h - 1, vector<int>(n - 1));
        for(int i = 0; i < h - 1; i++)
            for(int j = 0; j < n - 1; j++) cin >> field[i][j];
        parts[c] = Part(field);
    }

    int e;
    cin >> e;
    cin.ignore();
    while(e--) {
        string s;
        getline(cin, s);

        State ptr = s.begin();
        Part ans = tasu(ptr);

        for(int i = 0; i < n; i++) {
            cout << ans.p[i] + 1 << " \n"[i + 1 == n];
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3516
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<int> compose(const vector<int>& p, const vector<int>& q) {
    assert(p.size() == q.size());
    int n = p.size();
    vector<int> r(n);
    for (int i = 0; i < n; ++i) {
        r[i] = p[q[i]];
    }
    return r;
}
vector<int> pow(vector<int> p, long long k) {
    int n = p.size();
    vector<int> res(n);
    iota(res.begin(), res.end(), 0);
    for (; k; k >>= 1) {
        if (k & 1) res = compose(res, p);
        p = compose(p, p);
    }
    return res;
}

bool is_digit(char c) {
    return '0' <= c and c <= '9';
}

pair<int, int> read_int(const string& s, int i) {
    int j = i;
    while (is_digit(s[j])) ++j;
    return { stoi(s.substr(i, j - i)), j };
}

int main() {
    int n, k;
    cin >> n >> k;

    array<vector<int>, 256> ps{};
    for (int i = 0; i < k; ++i) {
        char id;
        cin >> id;
        int h;
        cin >> h;
        
        vector<int> p(n);
        iota(p.begin(), p.end(), 0);
        for (int j = 0; j < h - 1; ++j) {
            for (int c = 0; c < n - 1; ++c) {
                int g;
                cin >> g;
                if (g == 1) swap(p[c], p[c + 1]);
            }
        }
        ps[id] = move(p);
    }

    int m;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        string s;
        cin >> s;
        int l = s.size();
        vector<int> rp(l, -1);
        vector<int> st;
        for (int pos = 0; pos < l; ++pos) {
            if (s[pos] == '(') {
                st.push_back(pos);
            } else if (s[pos] == ')') {
                rp[st.back()] = pos;
                st.pop_back();
            }
        }
        auto scan = [&](auto scan, int l, int r) -> vector<int> {
            vector<int> res(n);
            iota(res.begin(), res.end(), 0);
            for (int i = l; i < r;) {
                int c = 1;
                if (is_digit(s[i])) {
                    auto [v, j] = read_int(s, i);
                    c = v;
                    i = j;
                }
                if (s[i] == '(') {
                    int j = rp[i];
                    res = compose(res, pow(scan(scan, i + 1, j), c));
                    i = j + 1;
                } else {
                    res = compose(res, pow(ps[s[i]], c));
                    i = i + 1;
                }
                if (i < r) {
                    assert(s[i] == '+');
                    ++i;
                }
            }
            return res;
        };
        auto ans = scan(scan, 0, l);
        for (int i = 0; i < n; ++i) {
            cout << ans[i] + 1 << " \n"[i == n - 1];
        }
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3444
final_rank: 11

code_snippet: #define _USE_MATH_DEFINES
#include<bits/stdc++.h>
#include<unordered_map>

using namespace std;
#define LP(I,S,G) for (long long int I = (S); I < (G); I++)
#define IN(X) 	for (int in = 0; in < X.size(); in++)cin >> X[in]
#define OUT(X) 	for (int in = 0; in < X.size(); in++)cout << X[in]<<" "
#define SORT(X) sort((X).begin(), (X).end())
#define CSORT(X,Y) sort(X.begin(), X.end(),Y)
#define COPY(X,Y) copy(X.begin(), X.end(), Y.begin())
#define ALL(X,Y) for (auto X = (Y).begin(); X != (Y).end(); X++)
#define FULL(a)  (a).begin(),(a).end()
#define BFS(Q,S) for(Q.push(S);Q.size()!=0;Q.pop())
typedef long long int ll;
typedef unsigned long long int ull;
long long int M = 1000000000000+39;


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

ll MAX(ll A, ll B) { return ((A) > (B) ? (A) : (B)); }
ll MIN(ll A, ll B) { return ((A) < (B) ? (A) : (B)); }
long long int xor128() {
	static long long int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
	long long int t = (x ^ (x << 11));
	x = y; y = z; z = w;
	return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

struct HashPair {
	//注意 constがいる
	template<class T1, class T2>
	size_t operator()(const pair<T1, T2> &p) const {
		//first分をハッシュ化する
		auto hash1 = hash<T1>{}(p.first);
		//second分をハッシュ化する
		auto hash2 = hash<T2>{}(p.second);
		//重複しないようにハッシュ処理
		size_t seed = 0;
		seed ^= hash1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		seed ^= hash2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		return seed;
	}
};
template<class I1, class I2>
istream& operator>>(istream& s, pair<I1, I2>& in) {
	s >> in.first >> in.second;
	return s;
}
vector<ll> add(vector<ll> l, vector<ll> r) {
	vector<ll> ret(l.size());
	ll n = l.size();
	LP(i, 0, n)ret[i] = l[r[i]];
	return ret;
}

vector<ll> mult(ll val, vector<ll> p) {
	ll lv = ceil(log(val) / log(2)), n = p.size();
	vector<vector<ll>> t(lv+1, vector<ll>(n));
	t[0] = p;
	LP(i, 0, lv) {
		t[i + 1] = add(t[i], t[i]);
	}
	vector<ll> ret(n);
	LP(i, 0, n)ret[i] = i;
	LP(i, 0, lv+1) {
		if ((val&((ll)1 << i)) != 0)ret = add(ret, t[i]);
	}
	return ret;
}

vector<ll> solve(ll now,ll n,string &s, vector<vector<ll>>& t ) {
	vector<ll> ret(t[0].size());
	LP(i, 0, ret.size())ret[i] = i;
	while (now != n) {
		if (s[now] == '+') {
			now++;
			continue;
		}
		else {
			if (s[now] >= '0'&&s[now] <= '9') {
				ll val = 0;
				while (s[now] >= '0'&&s[now] <= '9') {
					val *= 10;
					val += s[now] - '0';
					now++;
				}
				vector<ll> op(ret.size());
				if (s[now] == '(') {
					ll cnt = 1;
					ll next = now;
					while (cnt != 0) {
						next++;
						if (s[next] == '(')cnt++;
						if (s[next] == ')')cnt--;
					}
					op=solve(now + 1, next, s, t);
					now = next + 1;
				}
				else {
					op = t[s[now] - 'A'
];
					now++;
				}
				op = mult(val, op);
				ret = add(ret, op);
			}
			else {
				if (s[now] == '(') {
					vector<ll> op(ret.size());
					ll cnt = 1;
					ll next = now;
					while (cnt != 0) {
						next++;
						if (s[next] == '(')cnt++;
						if (s[next] == ')')cnt--;
					}
					op = solve(now + 1, next, s, t);
					now = next + 1;
					ret = add(ret, op);
				}
				else {
					ret = add(ret, t[s[now] - 'A']);
					now++;
				}
			}
		}
	}
	return ret;
}


int main() {
	ll n, k;
	cin >> n >> k;
	vector<ll> ans(n);
	vector<vector<ll>> t(26, vector<ll>(n));
	LP(i, 0, n) {
		ans[i] = i;
		LP(j, 0, 26)t[j][i] = i;
	}
	LP(i, 0, k) {
		ll p;
		char c;
		cin >> c;
		p = c - 'A';
		ll max;
		cin >> max;
		LP(j, 0, max-1) {
			vector<ll> s(n - 1);
			IN(s);
			LP(x, 0, n - 1) {
				if (s[x])swap(t[p][x], t[p][x + 1]);
			}
		}
	}
	ll e;
	cin >> e;
	LP(i, 0, e) {
		string sub,s="+";
		cin >> sub;
		LP(k, 0, sub.size()) {
			s.push_back(sub[k]);
			if (sub[k] == '(')s.push_back('+');
		}
		vector<ll> ans = solve(0, s.size(), s, t);
		ALL(i, ans)cout << *i + 1 << ((i==(ans.end()-1))?"\n":" ");
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3576
final_rank: 18

code_snippet: /*
　　　∫ ∫ ∫
　　　ノヽ
　　（＿　 ）
　（＿　　　 ）
（＿＿＿＿＿＿ ）
　ヽ(´･ω･)ﾉ　
　　 |　 /
　　 UU
*/
#pragma region macro
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
#include <vector>
#include <cassert>
#include <cmath>
#include <utility>
#include <tuple>
#include <map>
#include <set>
#include <deque>
#include <queue>
typedef long long int64;
using namespace std;
typedef vector<int> vi;
const int MOD = (int)1e9 + 7;
const int64 INF = 1LL << 62;
const int inf = 1<<30;
const char bn = '\n';
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
#define REP(i, n) for (int i = 0; i < (n); i++)
#define ALL(obj) (obj).begin(), (obj).end() //コンテナじゃないと使えない!!
#define debug(x) cerr << #x << ": " << (x) << "\n";
#define mp make_pair
template <typename T>
ostream& operator<<(ostream& os, const vector<T> &V){
    int N = V.size();
    REP(i,N){
        os << V[i]+1;
        if (i!=N-1) os << " ";
    }
    os << "\n";
    return os;
}
template <typename T,typename S>
ostream& operator<<(ostream& os, pair<T,S> const&P){
    os << "(";
    os << P.first;
    os << " , ";
    os << P.second;
    os << ")";
    return os;
}
template <typename T,typename S,typename U>
ostream& operator<<(ostream& os, tuple<T,S,U> const& P){
    os << "(";
    os << get<0>(P);
    os << ", ";
    os << get<1>(P);
    os << ", ";
    os << get<2>(P);
    os << ")";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T> &S){
    auto it=S.begin();
    while(it!=S.end()){
        os << *it;
        os << " ";
        it++;
    }
    os << "\n";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, deque<T> &q){
    for(auto it=q.begin();it<q.end();it++){
        os<<*it;
        os<<" ";
    }
    os<<endl;
    return os;
}
template <typename T,typename S>
ostream& operator<<(ostream& os, map<T,S> const&M){
    for(auto e:M){
        os<<e;
    }
    os<<endl;
    return os;
}
vector<pair<int,int>> dxdy = {mp(0,1),mp(1,0),mp(-1,0),mp(0,-1)};
#pragma endregion
//fixed<<setprecision(10)<<ans<<endl;



map<char, vector<int>> to;
int N;

// 構文解析
/*
    構文解析でよくあるバグは次の二つです。
    - begin++をし忘れる
    - getlineとcinの混合
*/



typedef string::const_iterator State;
class ParseError {};

// beginがexpectedを指していたらbeginを一つ進める。
void consume(State &begin, char expected) {
    if (*begin == expected) {
        begin++;
    } else {
        cerr << "Expected '" << expected << "' but got '" << *begin << "'"
            << endl;
        cerr << "Rest string is '";
        while (*begin) {
            cerr << *begin++;
        }
        cerr << "'" << endl;
        throw ParseError();
    }
}
void print_rest_string(State begin){
    cerr << "Rest string is '";
    while (*begin) {
        cerr << *begin++;
    }
    cerr << "'" << endl;
}

// amida[i]=j <- iにいたやつがjにいく
vector<int> go_through_amida(vector<int> const& prev, vector<int> const& amida){
    vector<int> res(prev.size(), 0);
    REP(i,amida.size()){
        // i にいたやつ prev[i] は amida[i] にいく
        res[i] = prev[amida[i]];
    }
    return res;
}

vector<int> init_amida(int N){
    vector<int> res(N, 0);
    REP(i,N) res[i] = i;
    return res;
}


vector<int> expression(State &begin);
vector<int> factor(State &begin);
vector<int> term(State &begin);
int number(State &begin);

// 四則演算の式をパースして、その評価結果を返す。
vector<int> expression(State &begin){
    vector<int> res = term(begin);

    while(true){
        if(*begin == '+'){
            consume(begin, '+');
            auto amida = term(begin);
            res = go_through_amida(res, amida);
        }else{
            break;
        }
    }

    return res;
}

// 乗算除算の式をパースして、その評価結果を返す。
vector<int> term(State &begin){
    vector<int> res = init_amida(N);
    
    if(isdigit(*begin)){
        int val = number(begin);

        auto amida = factor(begin);

        //ここで二分法でresを計算
        while(val){
            if(val & 1){
                res = go_through_amida(res, amida);
            }
            amida = go_through_amida(amida, amida);
            val/=2;
        }
    }else{
        char P; P = *begin++;
        res = to[P];
    }


    return res;
}

vector<int> factor(State &begin){
    if(*begin == '('){
        consume(begin, '('); // '('を飛ばす。
        auto res = expression(begin);
        consume(begin, ')'); // ')'を飛ばす。
        return res;
    }else{
        char P = *begin++;
        return to[P];
    }
}



// 数字の列をパースして、その数を返す。
int number(State &begin){
    int res = 0;
    while(isdigit(*begin)){
        res *= 10;
        res += *begin - '0';
        begin++;
    }

    return res;
}

void solve(string S){
    State begin = S.begin();
    vector<int> ans = expression(begin);
    cout << ans;
}


int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int K; cin >> N >> K;
    char P; int H;
    REP(_,K){
        cin >> P >> H;
        to[P] = init_amida(N);
        REP(j, H-1){
            REP(i, N-1){
                int g; cin >> g;
                if(g==1){
                    swap(to[P][i], to[P][i+1]);
                }
            }
        }
    }
    int E; cin >> E;
    REP(_, E){
        string S; cin >> S;
        solve(S);

    }

}
accuracy: 1
time_ms: 10
memory_kb: 3396
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
vector<int> parse(vector<vector<int>> &P, int N, string &S, int &p){
	int x = 0;
	while (isdigit(S[p]) != 0){
	  x = x * 10 + (S[p] - '0');
	  p++;
	}
	if (x == 0){
	  x = 1;
	}
	vector<int> r;
  if (isalpha(S[p]) != 0){
    r = P[S[p] - 'A'];
    p++;
  } else {
    p++;
    r = vector<int>(N);
    for (int i = 0; i < N; i++){
      r[i] = i;
    }
    while (true){
      vector<int> res = parse(P, N, S, p);
      vector<int> r2(N);
      for (int i = 0; i < N; i++){
        r2[i] = r[res[i]];
      }
      swap(r, r2);
      if (S[p] != '+'){
        break;
      }
      p++;
    }
    p++;
  }
  vector<int> ans(N);
  for (int i = 0; i < N; i++){
    ans[i] = i;
  }
  while (x > 0){
    if (x % 2 == 1){
      vector<int> ans2(N);
      for (int i = 0; i < N; i++){
        ans2[i] = ans[r[i]];
      }
      swap(ans, ans2);
    }
    vector<int> r2(N);
    for (int i = 0; i < N; i++){
      r2[i] = r[r[i]];
    }
    swap(r, r2);
    x /= 2;
  }
  return ans;
}
int main(){
  int N, K;
  cin >> N >> K;
  vector<char> p(K);
  vector<int> h(K);
  vector<vector<vector<int>>> g(K);
  for (int i = 0; i < K; i++){
    cin >> p[i] >> h[i];
    g[i] = vector<vector<int>>(h[i] - 1, vector<int>(N - 1));
    for (int j = 0; j < h[i] - 1; j++){
      for (int k = 0; k < N - 1; k++){
        cin >> g[i][j][k];
      }
    }
  }
  vector<vector<int>> P(26, vector<int>(N));
  for (int i = 0; i < 26; i++){
    for (int j = 0; j < N; j++){
      P[i][j] = j;
    }
  }
  for (int i = 0; i < K; i++){
    int id = p[i] - 'A';
    for (int j = 0; j < h[i] - 1; j++){
      for (int k = 0; k < N - 1; k++){
        if (g[i][j][k] == 1){
          swap(P[id][k], P[id][k + 1]);
        }
      }
    }
  }
  int E;
  cin >> E;
  for (int i = 0; i < E; i++){
    string S;
    cin >> S;
    S = "1(" + S + ")";
    int x = 0;
    vector<int> ans = parse(P, N, S, x);
    for (int j = 0; j < N; j++){
      cout << ans[j] + 1;
      if (j < N - 1){
        cout << ' ';
      }
    }
    cout << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3424
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

vector<int> mult(vector<int> a,vector<int> b){
    vector<int> res(a.size());
    rep(i,a.size()){
        res[i] = b[a[i]];
    }
    return res;
}

vector<int> input(int n,int h){
    vector<int> ami(n);
    iota(all(ami),0);
    rep(_,h-1){
        rep(x,n-1){
            if(in()){
                swap(ami[x],ami[x+1]);
            }
        }
    }
    vector<int> res(n);
    rep(i,n){
        res[ami[i]] = i;
    }
    return res;
}

vector<int> rev(vector<int> line){
    vector<int> res(line.size());
    rep(i,line.size()){
        res[line[i]] = i;
    }
    return res;
}

template <class t>
t pow(t x,ll y,function<t(t,t)> f,t e){
    t res = e;
    while(y){
        if(y&1)res = f(res,x);
        x = f(x,x);
        y >>= 1;
    }
    return res;
}

vvector<int> func(){
    int n = in();
    map<char,vector<int>> changes;
    {
        int m = in();
        rep(_,m){
            char c = in<char>();
            int h = in();
            changes[c] = input(n,h);
        }
    }
    vector<int> e(n);
    iota(all(e),0);
    using P = pair<vector<int>,int>;
    method(is_number,bool,char c){
        return '0' <= c and c <= '9';
    };
    method(read_number,pll,string &str,int p){
        ll res = 0;
        while(p < str.size() and is_number(str[p])){
            res = res * 10 + str[p] - '0';
            ++p;
        }
        return pll(res,p);
    };
    method(assemble,P,string &str,int p){
        auto res = e;
        while(p < str.size()){
            if(str[p]==')')break;
            if(str[p]=='('){
                P v = assemble(str,p+1);
                res = mult(res,v.first);
                p = v.second;
                continue;
            }
            if(is_number(str[p])){
                pll v = read_number(str,p);
                if(str[v.second]=='('){
                    P v2 = assemble(str,v.second+1);
                    res = mult(res,pow<vector<int>>(v2.first,v.first,mult,e));
                    p = v2.second;
                }else{
                    res = mult(res,pow<vector<int>>(changes[str[v.second]],v.first,mult,e));
                    p = v.second + 1;
                }
                continue;
            }
            if(str[p]=='+'){
                ++p;
                continue;
            }
            res = mult(res,changes[str[p]]);
            ++p;
        }
        return P(res,p+1);
    };
    int q = in();
    vvector<int> res;
    rep(_,q){
        string expression = in<string>();
        vector<int> add = assemble(expression,0).first;
        add = rev(add);
        foreach(i,add)++i;
        res.emplace_back(add);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3508
final_rank: 16

code_snippet: #define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<sstream>
#include<regex>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<iomanip>
#include<random>
using namespace std;
#define int long long
#define uint unsigned long long
const int mod=1e9+7;
const int inf=mod*mod;
const double eps=1e-10;
typedef vector<int>rep;
rep concat(rep a,rep b){
	rep ans(a.size());
	for(int i=0;i<a.size();i++)
		ans[i]=a[b[i]];
	return ans;
}
rep repet(rep a,int n){
	rep ans(a.size());
	iota(ans.begin(),ans.end(),0);
	while(n){
		if(n&1)
			ans=concat(ans,a);
		a=concat(a,a);
		n>>=1;
	}
	return ans;
}
rep amida[26];
typedef string::const_iterator state;
rep expr(state&it);
int number(state&it){
	int ret;
	for(ret=0;'0'<=*it&&*it<='9';it++)
		ret=ret*10+*it-'0';
	return ret;
}
rep factor(state&it){
	if('A'<=*it&&*it<='Z')
		return amida[*it++-'A'];
	rep ret=expr(++it);
	it++;
	return ret;
}
rep term(state&it){
	int num=1;
	if('0'<=*it&&*it<='9')
		num=number(it);
	rep ret=factor(it);
	return repet(ret,num);
}
rep expr(state&it){
	rep ret=term(it);
	while(*it=='+')
			ret=concat(ret,term(++it));
	return ret;
}
signed main(){
	int n,k;
	cin>>n>>k;
	for(int i=0;i<k;i++){
		char p;
		int h;
		cin>>p>>h;
		amida[p-'A'].resize(n);
		iota(amida[p-'A'].begin(),amida[p-'A'].end(),0);
		for(int j=0;j<h-1;j++){
			for(int l=0;l<n-1;l++){
				int g;
				cin>>g;
				if(g==1)
					swap(amida[p-'A'][l],amida[p-'A'][l+1]);
			}
		}
	}
	int e;
	cin>>e;
	cin.ignore();
	string expression;
	while(getline(cin,expression)){
		expression+=',';
		state it=expression.begin();
		rep ans=expr(it);
		for(int i=0;i<n;i++)
			cout<<ans[i]+1<<(i==n-1?'\n':' ');
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3448
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;
typedef long long ll;
typedef pair<ll,ll>P;

const int MOD=1000000007;
const int INF=0x3f3f3f3f;
const ll INFL=0x3f3f3f3f3f3f3f3f;

char C[2];

vector<int>operator+(vector<int>a,vector<int>&b){
	rep(i,a.size()){
		a[i]=b[a[i]];
	}
	return a;
}

vector<int>ppow(vector<int>a,int b){
	vector<int>res(a.size());
	rep(i,res.size())res[i]=i;
	while(b){
		if(b&1)res=res+a;
		a=a+a;
		b>>=1;
	}
	return res;
}

vector<int>p[26];


vector<int>expr(string&s,int&i);
vector<int>term(string&s,int&i);

vector<int>expr(string&s,int&i){//'+'
	vector<int>l=term(s,i);
	while(s[i]=='+'){
		i++;
		vector<int>r=term(s,i);
		l=l+r;
	}
	return l;
}

vector<int>term(string&s,int&i){
	int d=0;
	while(isdigit(s[i])){
		d=d*10+s[i]-'0';
		i++;
	}
	if(d==0)d=1;
	if(isalpha(s[i])){
		vector<int>res=ppow(p[s[i]-'A'],d);
		i++;
		return res;
	}
	else{
		assert(s[i]=='(');
		i++;
		vector<int>res=expr(s,i);
		i++;
		res=ppow(res,d);
		return res;
	}
}

int main(){
	int n,K;cin>>n>>K;
	rep(i,K){
		int h;scanf("%s%d",C,&h);
		vector<int>v(n);
		rep(j,n)v[j]=j;
		rep(j,h-1){
			rep(k,n-1){
				int g;scanf("%d",&g);
				if(g==1)swap(v[k],v[k+1]);
			}
		}
		vector<int>u(n);
		rep(j,n)u[v[j]]=j;
		p[C[0]-'A']=u;
	}
	int E;scanf("%d",&E);
	rep(Case,E){
		string s;cin>>s;
		int i=0;
		auto res=expr(s,i);
		vector<int>ans(n);
		rep(j,n){
			ans[res[j]]=j;
		}
		rep(j,ans.size()){
			if(j)printf(" ");
			printf("%d",ans[j]+1);
		}
		puts("");
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3304
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
using ull=unsigned long long;
using uint=unsigned int;
using pcc=pair<char,char>;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using pdd=pair<double,double>;
using tuplis=pair<ll,pll>;
using tuplis2=pair<pll,ll>;
template<class T> using pq=priority_queue<T,vector<T>,greater<T>>;
const ll LINF=0x1fffffffffffffff;
const ll MINF=0x7fffffffffff;
const int INF=0x3fffffff;
const ll MOD=1000000007;
const ll MODD=998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.141592653589793238462643383279;
const vector<ll>four{0,1,0,-1,0};
#define _overload4(_1,_2,_3,_4,name,...) name
#define _overload3(_1,_2,_3,name,...) name
#define _rep1(n) for(ll i=0;i<n;++i)
#define _rep2(i,n) for(ll i=0;i<n;++i)
#define _rep3(i,a,b) for(ll i=a;i<b;++i)
#define _rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) _overload4(__VA_ARGS__,_rep4,_rep3,_rep2,_rep1)(__VA_ARGS__)
#define _rrep1(n) for(ll i=(n)-1;i>=0;i--)
#define _rrep2(i,n) for(ll i=(n)-1;i>=0;i--)
#define _rrep3(i,a,b) for(ll i=(b)-1;i>=a;i--)
#define _rrep4(i,a,b,c) for(ll i=a+(b-a-1)/c*c;i>=a;i-=c)
#define rrep(...) _overload4(__VA_ARGS__,_rrep4,_rrep3,_rrep2,_rrep1)(__VA_ARGS__)
#define each(i,a) for(auto &i:a)
#define sum(...) accumulate(range(__VA_ARGS__),0LL)
#define dsum(...) accumulate(range(__VA_ARGS__),double(0))
#define _range(i) (i).begin(),(i).end()
#define _range2(i,k) (i).begin(),(i).begin()+k
#define _range3(i,a,b) (i).begin()+a,(i).begin()+b
#define range(...) _overload3(__VA_ARGS__,_range3,_range2,_range)(__VA_ARGS__)
#define _rrange(i) (i).rbegin(),(i).rend()
#define _rrange2(i,k) (i).rbegin(),(i).rbegin()+k
#define _rrange3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rrange(...) _overload3(__VA_ARGS__,_rrange3,_rrange2,_rrange)(__VA_ARGS__)
#define elif else if
#define unless(a) if(!(a))
#define mp make_pair
#define mt make_tuple
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type> name(__VA_ARGS__)
#define VEC(type,name,size) vector<type> name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
inline constexpr ll gcd(ll a,ll b){if(!a||!b)return 0;while(b){ll c=b;b=a%b;a=c;}return a;}
inline constexpr ll lcm(ll a,ll b){if(!a||!b)return 0;return a*b/gcd(a,b);}
template<class T> inline constexpr T min(vector<T> &v){return *min_element(range(v));}
inline char min(string &v){return *min_element(range(v));}
template<class T> inline constexpr T max(vector<T> &v){return *max_element(range(v));}
inline char max(string &v){return *max_element(range(v));}
inline constexpr ll intpow(ll a,ll b){ll ans=1;for(ll i=1;b;i*=2){if(b&i){b^=i;ans*=a;}a*=a;}return ans;}
template<typename T>
inline constexpr bool chmin(T &mn,const T &cnt){if(mn>cnt){mn=cnt;return 1;}else return 0;}
template<typename T>
inline constexpr bool chmax(T &mx,const T &cnt){if(mx<cnt){mx=cnt;return 1;}else return 0;}
template<class T> unordered_map<T,ll> press(vector<T> &a){ auto b = a; sort(range(b)); b.erase(unique(range(b)), b.end()); unordered_map<T,ll> ans; rep(b.size()) ans[b[i]] = i; each(i, a) i = ans[i]; return ans; }
template<class T> map<T,ll> press_map(vector<T> &a){ auto b = a; sort(range(b)); b.erase(unique(range(b)), b.end()); map<T,ll> ans; rep(b.size()) ans[b[i]] = i; each(i, a) i = ans[i]; return ans; }
inline int scan(){ return getchar(); }
inline void scan(int &a){ scanf("%d", &a); }
inline void scan(unsigned &a){ scanf("%u", &a); }
inline void scan(long &a){ scanf("%ld", &a); }
inline void scan(long long &a){ scanf("%lld", &a); }
inline void scan(unsigned long long &a){ scanf("%llu", &a); }
inline void scan(char &a){ cin >> a; }
inline void scan(float &a){ scanf("%f", &a); }
inline void scan(double &a){ scanf("%lf", &a); }
inline void scan(long double &a){ scanf("%Lf", &a); }
inline void scan(vector<bool> &vec){ for(unsigned i = 0; i < vec.size(); i++) { int a; scan(a); vec[i] = a; } }
inline void scan(string &a){ cin >> a; }
template<class T> inline void scan(vector<T> &vec);
template<class T, size_t size> inline void scan(array<T, size> &vec);
template<class T, class L> inline void scan(pair<T, L> &p);
template<class T, size_t size> inline void scan(T (&vec)[size]);
template<class T> inline void scan(vector<T> &vec){ for(auto &i : vec) scan(i); }
template<class T, size_t size> inline void scan(array<T, size> &vec){ for(auto &i : vec) scan(i); }
template<class T, class L> inline void scan(pair<T, L> &p){ scan(p.first); scan(p.second); }
template<class T, size_t size> inline void scan(T (&vec)[size]){ for(auto &i : vec) scan(i); }
template<class T> inline void scan(T &a){ cin>>a; }
inline void in(){}
template <class Head, class... Tail> inline void in(Head &head, Tail&... tail){ scan(head); in(tail...); }
inline void print(){ putchar(' '); }
inline void print(const bool &a){ printf("%d", a); }
inline void print(const int &a){ printf("%d", a); }
inline void print(const unsigned &a){ printf("%u", a); }
inline void print(const long &a){ printf("%ld", a); }
inline void print(const long long &a){ printf("%lld", a); }
inline void print(const unsigned long long &a){ printf("%llu", a); }
inline void print(const char &a){ printf("%c", a); }
inline void print(const char a[]){ printf("%s", a); }
inline void print(const float &a){ printf("%.15f", a); }
inline void print(const double &a){ printf("%.15f", a); }
inline void print(const long double &a){ printf("%.15Lf", a); }
template<class T> void print(const vector<T> &vec);
template<class T, size_t size> void print(const array<T, size> &vec);
template<class T, class L> void print(const pair<T, L> &p);
template<class T, size_t size> inline void print(const T (&vec)[size]);
template<class T> void print(const vector<T> &vec){ if(vec.empty()) return; print(vec[0]); for(auto i = vec.begin(); ++i != vec.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size> &vec){ print(vec[0]); for(auto i = vec.begin(); ++i != vec.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L> &p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> inline void print(const T (&vec)[size]){ print(vec[0]); for(auto i = vec; ++i != end(vec); ){ putchar(' '); print(*i); } }
template<class T> inline void print(const T &a){ cout << a; }
inline int out(){ putchar('\n'); return 0; }
template<class T> inline int out(const T &t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> inline int out(const Head &head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
template <class T> inline void err(T t){cerr<<t<<'\n';}
inline void err(){cerr<<'\n';}
inline int first(const bool &i){return out(i?"first":"second");}
inline int yes(const bool &i){return out(i?"yes":"no");}
inline int Yes(const bool &i){return out(i?"Yes":"No");}
inline int YES(const bool &i){return out(i?"YES":"NO");}
inline int Yay(const bool &i){return out(i?"Yay!":":(");}
inline int Possible(const bool &i){return out(i?"Possible":"Impossible");}
inline int POSSIBLE(const bool &i){return out(i?"POSSIBLE":"IMPOSSIBLE");}
inline void Case(ll i){printf("Case #%lld: ",i);}



struct Permutation { // 0-indexed
    vector<ll> perm;
    Permutation(initializer_list<ll>&& perm): perm(perm) {}
    Permutation(vector<ll>&& perm): perm(perm) {}
    template<class T> Permutation(const initializer_list<T>& perm): perm(perm.begin(), perm.end()) {}
    template<class T> Permutation(const vector<T>& perm): perm(perm.begin(), perm.end()) {}
    static Permutation identity(ll n) { vector<ll> ans(n); iota(ans.begin(), ans.end(), 0); return ans; }
    Permutation inv() const { vector<ll> ans(perm.size()); rep(perm.size()) ans[perm[i]] = i; return ans; }
    Permutation operator* (const Permutation& x) const { vector<ll> ans(perm.size()); rep(perm.size()) ans[i] = perm[x.perm[i]]; return ans; }
    Permutation& operator*=(const Permutation& x) { vector<ll> ans(perm.size()); rep(perm.size()) ans[i] = perm[x.perm[i]]; perm.swap(ans); return *this; }
    Permutation pow(ll x) const {
        Permutation ans = identity(perm.size()), cnt = *this;
        while(x){
            if(x & 1) ans *= cnt;
            x /= 2;
            cnt *= cnt;
        }
        return ans;
    }
};
vector<Permutation>parts;
string s;
Permutation parse(ll l,ll r){
    Permutation ans=parts.back();
    while(r>l){
        if(s[l]>='0'&&s[l]<='9'){
            ll at=l;
            while(s[l]>='0'&&s[l]<='9')l++;
            if(s[l]=='('){
                ll cnt=1,at2=l;
                while(cnt){
                    l++;
                    if(s[l]=='(')cnt++;
                    if(s[l]==')')cnt--;
                }
                ans*=parse(at2+1,l).pow(stoll(s.substr(at,at2-at)));
                l+=2;
            }
            else{
                ans*=parts[s[l]-'A'].pow(stoll(s.substr(at,l-at)));
                l+=2;
            }
        }
        else{
            ans*=parts[s[l]-'A'];
            l+=2;
        }
    }
    return ans;
}
signed main(){
    LL(n,k);
    parts.assign(27,Permutation::identity(n));
    rep(k){
        CHR(c);
        LL(k);
        c-='A';
        auto& p=parts[c].perm;
        rep(k-1){
            VEC(ll,a,n-1);
            rep(n-1)if(a[i])swap(p[i],p[i+1]);
        }
    }
    LL(q);
    rep(q){
        in(s);
        auto ans=parse(0,s.size()).perm;
        each(i,ans)i++;
        out(ans);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3328
final_rank: 6

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
using namespace std;
int N,K;
void in(vector<vector<int> >&a)
{
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)a[i][j]=0;
	}
	int h;cin>>h;
	vector<int>s(N);
	iota(s.begin(),s.end(),0);
	for(;--h;)
	{
		for(int i=0;i<N-1;i++)
		{
			int u;cin>>u;
			if(u)swap(s[i],s[i+1]);
		}
	}
	for(int i=0;i<N;i++)
	{
		a[i][s[i]]=1;
	}
}
vector<vector<int> >mul(const vector<vector<int> >&a,const vector<vector<int> >&b)
{
	vector<vector<int> >ans(N,vector<int>(N,0));
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
		{
			for(int k=0;k<N;k++)ans[i][j]+=a[i][k]*b[k][j];
		}
	}
	return ans;
}
vector<vector<int> >power(const vector<vector<int> >&a,int n)
{
	vector<vector<int> >ans(N,vector<int>(N,0));
	vector<vector<int> >A(a);
	for(int i=0;i<N;i++)ans[i][i]=1;
	while(n)
	{
		if(n&1)
		{
			ans=mul(ans,A);
		}
		n/=2;
		A=mul(A,A);
	}
	return ans;
}
string s;int id;
vector<vector<int> >f(const vector<vector<vector<int> > >&A)
{
	vector<vector<int> >ans(N,vector<int>(N,0));
	for(int i=0;i<N;i++)ans[i][i]=1;
	int now=0;
	for(;id<s.size();id++)
	{
		if(s[id]=='(')
		{
			id++;
			ans=mul(power(f(A),now>0?now:1),ans);
			now=0;
		}
		else if(s[id]>='A'&&s[id]<='Z')
		{
			ans=mul(power(A[s[id]-'A'],now>0?now:1),ans);
			now=0;
		}
		else if(s[id]>='0'&&s[id]<='9')
		{
			now=now*10+s[id]-'0';
		}
		else if(s[id]==')')
		{
			break;
		}
	}
	return ans;
}
main()
{
	cin>>N>>K;
	vector<vector<vector<int> > >A(26,vector<vector<int> >(N,vector<int>(N)));
	for(int i=0;i<K;i++)
	{
		char c;cin>>c;
		in(A[c-'A']);
	}
	int E;cin>>E;
	for(;E--;)
	{
		cin>>s;
		id=0;
		vector<vector<int> >a=f(A);
		for(int i=0;i<N;i++)
		{
			if(i)cout<<" ";
			for(int j=0;j<N;j++)if(a[i][j]==1)cout<<j+1;
		}
		cout<<endl;
	}
}
accuracy: 1
time_ms: 660
memory_kb: 3304
final_rank: 19

code_snippet: #include <cstdio>
#include <cctype>
#include <cassert>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <numeric>

using Amida=std::vector<size_t>;

Amida append(const Amida &lhs, const Amida &rhs) {
  Amida res(lhs.size());
  std::iota(res.begin(), res.end(), 0);
  for (size_t i=0; i<res.size(); ++i)
    res[i] = rhs[lhs[i]];

  return res;
}

Amida repeat(const Amida &base, int times) {
  Amida res(base.size());
  std::iota(res.begin(), res.end(), 0);
  for (Amida dbl=base; times; times>>=1) {
    if (times & 1) res = append(res, dbl);
    dbl = append(dbl, dbl);
  }
  return res;
}

Amida parse(
    const std::string &s, size_t &i, const std::map<char, Amida> &expr,
    size_t preced=0) {

  if (preced == 1) {
    int times=1;
    if (isdigit(s[i])) {
      times = s[i]-'0';
      while (++i < s.length() && isdigit(s[i]))
        times = times*10+s[i]-'0';
    }
    if (isupper(s[i])) {
      Amida base=expr.at(s[i++]);
      return repeat(base, times);
    }
    if (s[i] == '(') {
      Amida base=parse(s, ++i, expr, 0);
      assert(s[i] == ')');
      ++i;
      return repeat(base, times);
    }
    assert(false);
  }

  Amida lhs=parse(s, i, expr, 1);
  while (i < s.length()) {
    char op=s[i];
    if (op != '+') break;
    Amida rhs=parse(s, ++i, expr, 1);
    lhs = append(lhs, rhs);
  }
  return lhs;
}

int main() {
  size_t N, K;
  scanf("%zu %zu", &N, &K);

  std::map<char, Amida> expr;
  for (size_t i=0; i<K; ++i) {
    char p;
    size_t h;
    scanf(" %c %zu", &p, &h);
    Amida g(N);
    std::iota(g.begin(), g.end(), 0);
    for (size_t r=1; r<h; ++r) {
      for (size_t c=1; c<N; ++c) {
        int f;
        scanf("%d", &f);
        if (f) std::swap(g[c-1], g[c]);
      }
    }
    Amida gg(N);
    for (size_t c=0; c<N; ++c)
      gg[g[c]] = c;

    expr[p] = gg;
  }

  size_t E;
  scanf("%zu", &E);
  for (size_t i=0; i<E; ++i) {
    char buf[1024];
    scanf("%s", buf);
    std::string s=buf;
    size_t j=0;
    Amida vla=parse(s, j, expr);
    Amida res(N);
    for (size_t k=0; k<N; ++k)
      res[vla[k]] = k;
    for (size_t k=0; k<N; ++k)
      printf("%zu%c", res[k]+1, k+1<N? ' ':'\n');
  }
}
accuracy: 1
time_ms: 10
memory_kb: 2908
final_rank: 1

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


typedef vector<int> V;
typedef vector<V> MATRIX;

int N;
int table[26][12][12];
char equation[1001];

MATRIX calc(MATRIX left,MATRIX right){

	MATRIX ret(N,V(N));

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++)ret[i][k] = 0;
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			for(int a = 0; a < N; a++){
				ret[row][col] += left[row][a]*right[a][col];
			}
		}
	}

	return ret;

}

//MULTのT乗を計算する
MATRIX pow(MATRIX MULT,int count){

	MATRIX ret(N,V(N));

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(row == col)ret[row][col] = 1;
			else{
				ret[row][col] = 0;
			}
		}
	}

	while(count > 0){
		if(count%2 == 1)ret = calc(ret,MULT);
		MULT = calc(MULT,MULT);
		count /= 2;
	}

	return ret;
}

MATRIX recursive(int left,int right){

	bool is_First = true;
	MATRIX RET(N,V(N)),CALC(N,V(N));
	int num;

	for(int i = left; i <= right; ){

		if(equation[i] >= '0' && equation[i] <= '9'){
			num = 0;
			while(equation[i] >= '0' && equation[i] <= '9'){
				num = 10*num+equation[i]-'0';
				i++;
			}

			if(equation[i] == '('){
				int depth = 0,close_pos;

				for(int k = i; ; k++){
					if(equation[k] == '(')depth++;
					else if(equation[k] == ')'){
						depth--;
						if(depth == 0){
							close_pos = k;
							break;
						}
					}
				}

				CALC = recursive(i+1,close_pos-1);

				CALC = pow(CALC,num);

				if(is_First){ //計算区間で、まだ行列が登場していない場合
					RET = CALC;
					is_First = false;
				}else{ //既に行列が登場している場合は、+で連結されているはず
					RET = calc(RET,CALC);
				}

				i = close_pos+1;

			}else{ //右に単項

				CALC = recursive(i,i);
				CALC = pow(CALC,num);

				if(is_First){ //計算区間で、まだ行列が登場していない場合
					RET = CALC;
					is_First = false;
				}else{ //既に行列が登場している場合は、+で連結されているはず
					RET = calc(RET,CALC);
				}
				i += 1;
			}

		}else if(equation[i] >= 'A' && equation[i] <= 'Z'){
			if(is_First){ //行列が初登場の場合

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						RET[row][col] = table[equation[i]-'A'][row][col];
					}
				}
				is_First = false;

			}else{ // ...+Xの形

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						CALC[row][col] = table[equation[i]-'A'][row][col];
					}
				}

				RET = calc(RET,CALC);

			}
			i++;
		}else{ //equation[i] == '+'
			i++;
		}
	}
	return RET;
}



int main(){

	int K;

	scanf("%d %d",&N,&K);

	for(int i = 0; i < 26; i++){
		for(int k = 0; k < N; k++){
			for(int p = 0; p < N; p++)table[i][k][p] = 0;
		}
	}

	int height,work[N],tmp;
	char buf[2];

	for(int loop = 0; loop < K; loop++){
		scanf("%s %d",buf,&height);

		for(int i = 0; i < N; i++)work[i] = i;

		//あみだくじの情報を計算
		for(int k = 0; k < height-1; k++){
			for(int loc = 0; loc < N-1; loc++){
				scanf("%d",&tmp);
				if(tmp == 1){
					swap(work[loc],work[loc+1]);
				}
			}
		}
		//遷移先を記録
		for(int i = 0; i < N; i++){
			table[buf[0]-'A'][work[i]][i] = 1;
		}
	}

	MATRIX RET(N,V(N));
	int E;
	scanf("%d",&E);

	int length,ans[N];

	for(int loop = 0; loop < E; loop++){
		scanf("%s",equation);

		for(length = 0; equation[length] != '\0'; length++);

		RET = recursive(0,length-1);

		for(int i = 0; i < N; i++){
			for(int k = 0; k < N; k++){
				if(RET[i][k] == 1){
					ans[k] = i;
					break;
				}
			}
		}

		for(int i = 0; i < N-1; i++){
			printf("%d ",ans[i]+1);
		}
		printf("%d\n",ans[N-1]+1);
	}

	return 0;
}
accuracy: 1
time_ms: 940
memory_kb: 3368
final_rank: 20

code_snippet: #include <string>
#include <vector>
#include <iostream>
using namespace std;
int N, K, Q, h, g; vector<int> p[32]; string s;
vector<int> merge(vector<int> p1, vector<int> p2) {
	vector<int> ret(N);
	for (int i = 0; i < N; i++) ret[i] = p2[p1[i]];
	return ret;
}
vector<int> unit(int, int);
vector<int> expr(int, int);
vector<int> unit(int l, int r) {
	if (r - l == 1) return p[s[l] - 65];
	vector<int> res; int mul = 0;
	for (int i = l; i < r; i++) {
		if (48 <= s[i] && s[i] <= 57) mul = mul * 10 + (s[i] - 48);
		else if (i != r - 1) {
			res = expr(i + 1, r - 1);
			break;
		}
		else res = p[s[i] - 65];
	}
	vector<int> ret(N);
	for (int i = 0; i < N; i++) ret[i] = i;
	while (mul >= 1) {
		if(mul & 1) ret = merge(ret, res);
		res = merge(res, res);
		mul >>= 1;
	}
	return ret;
}
vector<int> expr(int l, int r) {
	vector<int> ret(N);
	for (int i = 0; i < N; i++) ret[i] = i;
	int pl = l, depth = 0;
	for (int i = l; i <= r; i++) {
		if (i != r && s[i] == '(') depth++;
		if (i != r && s[i] == ')') depth--;
		if (depth == 0 && (i == r || s[i] == '+')) {
			ret = merge(ret, unit(pl, i));
			pl = i + 1;
		}
	}
	return ret;
}
int main() {
	cin >> N >> K;
	for (int i = 0; i < K; i++) {
		cin >> s >> h;
		vector<int> inv(N);
		for (int j = 0; j < N; j++) inv[j] = j;
		for (int j = 0; j < h - 1; j++) {
			for (int k = 0; k < N - 1; k++) {
				cin >> g;
				if (g == 1) swap(inv[k], inv[k + 1]);
			}
		}
		p[s[0] - 65].resize(N);
		for (int j = 0; j < N; j++) p[s[0] - 65][inv[j]] = j;
	}
	cin >> Q;
	while(Q--) {
		cin >> s;
		vector<int> res = expr(0, s.size());
		vector<int> ret(N);
		for (int i = 0; i < N; i++) ret[res[i]] = i;
		for (int i = 0; i < N; i++) {
			if (i) cout << ' ';
			cout << ret[i] + 1;
		}
		cout << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3120
final_rank: 3

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cassert>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <cassert>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
int n,k;
int x[30][25];
string S;
int cur = 0;
vector<int>expr();
vector<int>term(){
	if(S[cur] == '('){
		cur++; vector<int>V = expr(); cur++; return V;
	}
	if(0<=S[cur]-'A' && S[cur]-'A'<=25){
		int r = S[cur]-'A'; cur++;
		vector<int>V; for(int i=0;i<n;i++) V.pb(x[r][i]);
		return V;
	}
	int val = 0;
	while(0<=S[cur]-'0' && S[cur]-'0'<=9){
		val = val*10+(S[cur]-'0');
		cur++;
	}
	vector<int>rep = term(); 
	vector<int>now,nw(n); for(int i=0;i<n;i++) now.pb(i);
	while(val){
		if(val%2){
			for(int i=0;i<n;i++){
				nw[i] = now[rep[i]];
			}
			now = nw;
		}
		for(int i=0;i<n;i++){
			nw[i] = rep[rep[i]];
		} 
		rep = nw; val/=2;
	}
//for(int i=0;i<n;i++) cout << now[i] << endl;
	return now;
}
vector<int> expr(){
	vector<int>vi; for(int i=0;i<n;i++) vi.pb(i);
	do{
		if(S[cur] == '+') cur++;
		vector<int>ch = term();
		vector<int>nw(n); for(int i=0;i<n;i++) nw[i] = vi[ch[i]]; vi = nw;
	}while(cur<S.size() && S[cur] == '+');
	return vi;
}
int main(){
	cin >> n >> k;
	for(int i=0;i<k;i++){
		string s; cin >> s;
		int r; cin >> r;
		vector<int>V; for(int i=0;i<n;i++) V.pb(i);
		for(int iy=0;iy<r-1;iy++){
			for(int j=0;j<n-1;j++){
				int y; cin >> y; if(y) swap(V[j],V[j+1]);
			}
		}
		for(int j=0;j<n;j++) x[s[0]-'A'][j] = V[j];
	}
	int x; cin >> x;
	for(int i=0;i<x;i++){
		cin >> S;
		cur = 0; vector<int>vi = expr();
		for(int i=0;i<vi.size();i++) cout << vi[i]+1 << (i == n-1?'\n':' ');
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3196
final_rank: 4