Problem:
Problem J:
いにしえの数式
あなたの友人の考古学者が遺跡を発掘していた．
    ある日，彼は怪しげな記号の羅列が刻まれている石盤を大量に発見した．
    彼はこの大発見に大喜びし，すぐさま石盤に刻まれている記号の解読を始めた．
    何週間にもわたる彼の解読の努力の結果，
    どうやらこれらの石盤には変数・演算子・カッコの組み合わせで成り立っている
    数式のようなものが刻まれていることがわかった．
    発掘した石盤と遺跡に関わる文献を調べていくうちに彼はさらに，
    それぞれの石盤で演算子の結合規則が異なっており，
    それぞれの石盤の先頭に演算子の結合規則が記されているらしいことを突きとめた．
    しかし，彼は数学が苦手であるため，演算子の結合規則を見ても
    すぐには数式がどのように結合しているかがわからなかった．
    そこで彼は，優れたコンピュータサイエンティストであるあなたに
    「石盤に書かれている数式がどのように結合しているかを調べてほしい」
    と依頼してきた．
    あなたは，彼を手助けすることができるだろうか？
数式中に現れる演算子には優先順位が定められており，
    優先順位の高い演算子から順に結合していく．
    同一優先順位をもつ演算子にはそれぞれ結合方向が定められており，
    左から右に結合する場合は左にある演算子から順に，
    右から左に結合する場合は右にある演算子から順に結合していく．
    例えば，
+
より
*
の方が優先順位が高く，
*
が左から右に結合する場合，
    式
a+b*c*d
は
(a+((b*c)*d))
のように結合する．
    サンプル入力にも他の例がいくつか挙げられているので参照のこと．
Input
入力に与えられる数式は，以下の
Expr
で定義されるような文字列である．
    この定義において，
Var
は変数を表し，
Op
は演算子を表す．
Expr
::=
Var
|
Expr
Op
Expr
|
“
(
”
Expr
“
)
”
Var
::=
“
a
” |
	    “
b
” |
	    ... |
	    “
z
”
Op
::=
“
+
” |
	    “
-
” |
	    “
*
” |
	    “
/
” |
	    “
<
” |
	    “
>
” |
	    “
=
” |
	    “
&
” |
	    “
|
” |
	    “
^
”
演算子はすべて二項演算子であり，単項演算子やその他の演算子は存在しない．
入力は，いくつかのデータセットからなる．
    入力の先頭行にデータセット数
D
(
D
≤ 100)
    が与えられ，
    以降の行に
D
個のデータセットが続く．
それぞれのデータセットは，次のようなフォーマットで与えられる．
（演算子の結合規則の定義）
（クエリの定義）
演算子の結合規則の定義は，以下のようなフォーマットで与えられる．この定義において，
G
は演算子グループの数を表す数である．
G
（演算子グループ1 の定義）
（演算子グループ2 の定義）
...
（演算子グループ
G
の定義）
演算子は，結合の優先順位ごとにグループに分けられている．
    同一のグループに属する演算子は結合の優先順位が等しく，
    グループの定義が後に現れる演算子の方が
    前に現れる演算子より結合の優先順位が高い．
それぞれの演算子グループは，以下のように定義される．
A
M
p
1
p
2
...
p
M
A
は演算子の結合方向を表す文字で，
    “
L
” か “
R
” の
    いずれかである．
    “
L
” は左から右に結合することを表し，
    “
R
” は右から左に結合することを表す．
M
(
M
> 0)
    は演算子グループに含まれる演算子の数であり，
p
i
(1 ≤
i
≤
M
)
    はグループに含まれる演算子を表す文字である．
    同じ演算子がグループ内に2度現れることはなく，また，
    データセット内にグループをまたがって
    同じ演算子が2度現れることもない．
演算子の定義には，上記の
Op
で定義された演算子のみが現れる．
    1つのデータセットにおいて，必ず1つ以上の演算子が定義されると仮定してよい．
クエリの定義は以下のようなフォーマットで与えられる．
N
e
1
e
2
...
e
N
N
(0 <
N
≤ 50) はクエリとして与えられる
    数式の数である．
e
i
(1 ≤
i
≤
N
)
    は上記の
Expr
の定義を満たすような
    式を表す空でない文字列である．
e
i
の長さはたかだか100文字であり，
    当該データセットで定義されていない演算子は出現しないものと仮定してよい．
Output
データセットごとに，
    クエリとして与えられたそれぞれの式について，
    式中の各演算子について必ず1つのカッコの組を用いて
    すべての二項演算を正しく囲み，
    演算子の結合を表現した文字列を出力せよ．
    入力の式に現れる変数や演算子の順序を変更してはならない．
それぞれのデータセットの間には空行を出力せよ．
    出力の末尾に空行を出力してはならない．
Sample Input
2
3
R 1 =
L 2 + -
L 2 * /
6
a+b*c-d
(p-q)/q/d
a+b*c=d-e
t+t+t+t+t
s=s=s=s=s
(((((z)))))
3
R 3 = < >
L 3 & | ^
L 4 + - * /
1
a>b*c=d<e|f+g^h&i<j>k
Output for the Sample Input
((a+(b*c))-d)
(((p-q)/q)/d)
((a+(b*c))=(d-e))
((((t+t)+t)+t)+t)
(s=(s=(s=(s=s))))
z

(a>((b*c)=(d<((((e|(f+g))^h)&i)<(j>k)))))

Submitted solutions:

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



int G;
int CLOSE[105];
char LR[15];
map<char,int>MAP;


bool isWord(char ch){

	return ch >= 'a' && ch <= 'z';
}

string recursive(string line,int depth,int max_depth,int left,int right){

	if(line[left] == '(' && right == CLOSE[left]){

		return recursive(line,0,max_depth,left+1,right-1); //式なので0から再スタート
	}

	if(depth == max_depth+1){ //変数であるはず

		string ret = "";
		ret += line[left];

		return ret;
	}

	vector<int> vec;

	//depthの演算子があるかチェック
	int D = 0;

	for(int i = left; i <= right; i++){
		if(isWord(line[i]))continue;

		if(line[i] == '('){

			D++;
			continue;
		}else if(line[i] == ')'){

			D--;
			continue;
		}

		if(MAP[line[i]] == depth && D == 0){ //カッコの中に入っていたら不可

			vec.push_back(i);
		}
	}

	if(vec.size() == 0){

		return recursive(line,depth+1,max_depth,left,right);
	}

	string ret,work;

	if(LR[depth] == 'L'){

		ret = recursive(line,depth+1,max_depth,left,vec[0]-1);

		for(int i = 0; i < vec.size(); i++){
			ret += line[vec[i]];

			if(i == vec.size()-1){

				work = recursive(line,depth+1,max_depth,vec[i]+1,right);

			}else{

				work = recursive(line,depth+1,max_depth,vec[i]+1,vec[i+1]-1);
			}

			ret = "("+ret+work+")";
		}

	}else{ //LR[depth] == 'R'

		ret = recursive(line,depth+1,max_depth,vec[vec.size()-1]+1,right);

		for(int i = vec.size()-1; i >= 0; i--){
			ret = line[vec[i]]+ret;

			if(i == 0){

				work = recursive(line,depth+1,max_depth,left,vec[0]-1);

			}else{

				work = recursive(line,depth+1,max_depth,vec[i-1]+1,vec[i]-1);
			}

			ret = "("+work+ret+")";
		}
	}

	return ret;
}


void func(){

	MAP.clear();

	scanf("%d",&G);

	char buf[2];
	int tmp;

	for(int i = 0; i < G; i++){

		scanf("%s %d",buf,&tmp);

		LR[i] = buf[0];

		for(int k = 0; k < tmp; k++){

			scanf("%s",buf);
			MAP[buf[0]] = i;
		}
	}

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

	int max_depth;

	for(int loop = 0; loop < num_query; loop++){

		string line;
		cin >> line;

		stack<int> S;

		//カッコの対応関係
		for(int i = 0; i < line.length(); i++){
			if(line[i] == '('){

				S.push(i);
			}else if(line[i] == ')'){

				CLOSE[S.top()] = i;
				S.pop();
			}
		}

		max_depth = 0;

		for(int i = 0; i < line.length(); i++){
			if(line[i] == '(' || line[i] == ')' || isWord(line[i]))continue;

			max_depth = max(max_depth,MAP[line[i]]);
		}

		string ret = recursive(line,0,max_depth,0,line.length()-1);

		printf("%s\n",ret.c_str());
	}
}

int main(){

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

	for(int i = 0; i < num_case; i++){
		if(i > 0){

			printf("\n");
		}
		func();
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3200
final_rank: 15

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



int G;
int CLOSE[105];
char LR[15];
map<char,int>MAP;


bool isWord(char ch){

	return ch >= 'a' && ch <= 'z';
}

string recursive(string line,int depth,int max_depth,int left,int right){

	if(line[left] == '(' && right == CLOSE[left]){

		return recursive(line,0,max_depth,left+1,right-1); //式なので0から再スタート
	}

	if(depth == max_depth+1){ //変数であるはず

		string ret = "";
		ret += line[left];

		//printf("最大深さなので%sをreturn\n",ret.c_str());

		return ret;
	}

	vector<int> vec;

	//depthの演算子があるかチェック
	int D = 0;

	for(int i = left; i <= right; i++){
		if(isWord(line[i]))continue;

		if(line[i] == '('){

			D++;
			continue;
		}else if(line[i] == ')'){

			D--;
			continue;
		}

		if(MAP[line[i]] == depth && D == 0){ //カッコの中に入っていたら不可

			vec.push_back(i);
		}
	}

	if(vec.size() == 0){

		return recursive(line,depth+1,max_depth,left,right);
	}

	string ret,work;

	if(LR[depth] == 'L'){

		ret = recursive(line,depth+1,max_depth,left,vec[0]-1);

		for(int i = 0; i < vec.size(); i++){
			ret += line[vec[i]];

			if(i == vec.size()-1){

				work = recursive(line,depth+1,max_depth,vec[i]+1,right);

			}else{

				work = recursive(line,depth+1,max_depth,vec[i]+1,vec[i+1]-1);
			}

			ret = "("+ret+work+")";
		}

	}else{ //LR[depth] == 'R'

		ret = recursive(line,depth+1,max_depth,vec[vec.size()-1]+1,right);

		for(int i = vec.size()-1; i >= 0; i--){
			ret = line[vec[i]]+ret;

			if(i == 0){

				work = recursive(line,depth+1,max_depth,left,vec[0]-1);

			}else{

				work = recursive(line,depth+1,max_depth,vec[i-1]+1,vec[i]-1);
			}

			ret = "("+work+ret+")";
		}
	}

	return ret;
}


void func(){

	MAP.clear();

	scanf("%d",&G);

	char buf[2];
	int tmp;

	for(int i = 0; i < G; i++){

		scanf("%s %d",buf,&tmp);

		LR[i] = buf[0];

		for(int k = 0; k < tmp; k++){

			scanf("%s",buf);
			MAP[buf[0]] = i;
		}
	}

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

	int max_depth;

	for(int loop = 0; loop < num_query; loop++){

		string line;
		cin >> line;

		stack<int> S;

		//カッコの対応関係
		for(int i = 0; i < line.length(); i++){
			if(line[i] == '('){

				S.push(i);
			}else if(line[i] == ')'){

				CLOSE[S.top()] = i;
				//printf("CLOSE[%d]:%d\n",S.top(),i);
				S.pop();
			}
		}

		max_depth = 0;

		for(int i = 0; i < line.length(); i++){
			if(line[i] == '(' || line[i] == ')' || isWord(line[i]))continue;

			max_depth = max(max_depth,MAP[line[i]]);
		}

		string ret = recursive(line,0,max_depth,0,line.length()-1);

		printf("%s\n",ret.c_str());
	}
}

int main(){

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

	for(int i = 0; i < num_case; i++){
		if(i > 0){

			printf("\n");
		}
		func();
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3248
final_rank: 16

code_snippet: #include <cstdio>
#include <cstdint>
#include <cassert>
#include <string>
#include <vector>
#include <algorithm>

std::string parse(std::string const& s, size_t& i,
                  std::vector<std::string> const& ops, size_t preced = 0) {

  if (preced == ops.size()) {
    if (s[i] == '(') {
      auto res = parse(s, ++i, ops, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    assert(isalpha(s[i]));
    return std::string(1, s[i++]);
  }

  auto res = parse(s, i, ops, preced+1);
  int left = (ops[preced][0] == 'L');
  size_t leftparen = 0;
  while (i < s.length()) {
    char op = s[i];
    if (!std::count(ops[preced].begin()+1, ops[preced].end(), op)) break;
    auto tmp = parse(s, ++i, ops, preced+left);
    ++leftparen;
    res += op + tmp + ")";
  }
  return std::string(leftparen, '(') + res;
}

void solve_testcase() {
  size_t G;
  scanf("%zu", &G);

  std::vector<std::string> ops(G);
  for (size_t i = 0; i < G; ++i) {
    char A;
    size_t M;
    scanf(" %c %zu", &A, &M);
    ops[i] += A;
    for (size_t j = 0; j < M; ++j) {
      char op;
      scanf(" %c", &op);
      ops[i] += op;
    }
  }

  size_t N;
  scanf("%zu", &N);
  for (size_t i = 0; i < N; ++i) {
    char buf[128];
    scanf("%s", buf);
    std::string s = buf;
    size_t j = 0;
    printf("%s\n", parse(s, j, ops).c_str());
  }
}

int main() {
  int D;
  scanf("%d", &D);
  for (int i = 0; i < D; ++i) {
    if (i > 0) puts("");
    solve_testcase();
  }
}
accuracy: 1
time_ms: 30
memory_kb: 2784
final_rank: 9

code_snippet: #include <cstdio>
#include <cstdint>
#include <cassert>
#include <string>
#include <vector>
#include <algorithm>

std::string parse(std::string const& s, size_t& i,
                  std::vector<std::string> const& ops, size_t preced = 0) {

  if (preced == ops.size()) {
    if (s[i] == '(') {
      auto res = parse(s, ++i, ops, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    assert(isalpha(s[i]));
    return std::string(1, s[i++]);
  }

  auto res = parse(s, i, ops, preced+1);
  int left = (ops[preced][0] == 'L');
  while (i < s.length()) {
    char op = s[i];
    if (!std::count(ops[preced].begin()+1, ops[preced].end(), op)) break;
    auto tmp = parse(s, ++i, ops, preced+left);
    res = "(" + res + op + tmp + ")";
  }
  return res;
}

void solve_testcase() {
  size_t G;
  scanf("%zu", &G);

  std::vector<std::string> ops(G);
  for (size_t i = 0; i < G; ++i) {
    char A;
    size_t M;
    scanf(" %c %zu", &A, &M);
    ops[i] += A;
    for (size_t j = 0; j < M; ++j) {
      char op;
      scanf(" %c", &op);
      ops[i] += op;
    }
  }

  size_t N;
  scanf("%zu", &N);
  for (size_t i = 0; i < N; ++i) {
    char buf[128];
    scanf("%s", buf);
    std::string s = buf;
    size_t j = 0;
    printf("%s\n", parse(s, j, ops).c_str());
  }
}

int main() {
  int D;
  scanf("%d", &D);
  for (int i = 0; i < D; ++i) {
    if (i > 0) puts("");
    solve_testcase();
  }
}
accuracy: 1
time_ms: 20
memory_kb: 2664
final_rank: 6

code_snippet: #include <cstdio>
#include <cstdint>
#include <cassert>
#include <string>
#include <vector>
#include <algorithm>

std::string parse(std::string const& s, size_t& i,
                  std::vector<std::string> const& ops, size_t preced = 0) {

  if (preced == ops.size()) {
    if (s[i] == '(') {
      auto res = parse(s, ++i, ops, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    assert(isalpha(s[i]));
    return std::string(1, s[i++]);
  }

  auto res = parse(s, i, ops, preced+1);
  if (ops[preced][0] == 'L') {
    while (i < s.length()) {
      char op = s[i];
      if (!std::count(ops[preced].begin()+1, ops[preced].end(), op)) break;
      auto tmp = parse(s, ++i, ops, preced+1);
      res = "(" + res + op + tmp + ")";
    }
  } else {
    while (i < s.length()) {
      char op = s[i];
      if (!std::count(ops[preced].begin()+1, ops[preced].end(), op)) break;
      auto tmp = parse(s, ++i, ops, preced);
      res = "(" + res + op + tmp + ")";
    }
  }
  return res;
}

void solve_testcase() {
  size_t G;
  scanf("%zu", &G);

  std::vector<std::string> ops(G);
  for (size_t i = 0; i < G; ++i) {
    char A;
    size_t M;
    scanf(" %c %zu", &A, &M);
    ops[i] += A;
    for (size_t j = 0; j < M; ++j) {
      char op;
      scanf(" %c", &op);
      ops[i] += op;
    }
  }

  size_t N;
  scanf("%zu", &N);
  for (size_t i = 0; i < N; ++i) {
    char buf[128];
    scanf("%s", buf);
    std::string s = buf;
    size_t j = 0;
    printf("%s\n", parse(s, j, ops).c_str());
  }
}

int main() {
  int D;
  scanf("%d", &D);
  for (int i = 0; i < D; ++i) {
    if (i > 0) puts("");
    solve_testcase();
  }
}
accuracy: 1
time_ms: 20
memory_kb: 2744
final_rank: 7

code_snippet: #include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
using ld=long double;

struct Node {
	char var;
	vector<shared_ptr<Node>>chs;
	Node(char ch):var(ch) {

	}
	Node() :var('@') {

	}
};

shared_ptr<Node> term(const vector<int>&ways,map<char,int>mp,string st, int&a,int k) {
	shared_ptr<Node>no;
	if (st[a] == '(') {
		a++;
		auto ans=term(ways,mp,st,a,0);
		assert(st[a]==')');
		a++;
		no=ans;
	}
	else {
		assert(isalpha(st[a]));
		char var = st[a];
		a++;
		no = make_shared<Node>(var);
	}
		
	while (a != st.size() && st[a] != ')') {
		char op = st[a];
			
		if (mp[op] >= k) {
			a++;
			shared_ptr<Node>ans;
			if (ways[mp[op]] == 1) {
				ans = term(ways, mp, st, a, mp[op] + 1);
			}
			else {
				ans = term(ways, mp, st, a, mp[op]);
			}
			shared_ptr<Node>pa(make_shared<Node>(op));
			pa->chs = vector<shared_ptr<Node>>{ no,ans };
			no = pa;
		}
		else {
			break;
		}
	}
	return no;
		
	
}

string get_st(shared_ptr<Node>n) {
	if (isalpha(n->var)) {
		return string(1,n->var);
	}
	else {
		return "("+get_st(n->chs[0])+n->var+get_st(n->chs[1])+")";
	}
}

void solve(string st,map<char,int>ch_mp,const vector<int>&ways) {
	int k=0;
	int a=0;
	shared_ptr<Node>root(term(ways,ch_mp,st,a,0));
	string answer=get_st(root);
	cout<<answer<<endl;
}

int main() {


	int T;cin>>T;
	for (int t = 0; t < T; ++t) {
		int N; cin >> N;
		map<char, int>ch_mp;
		vector<int>ways(N);
		for (int i = 0; i < N; ++i) {
			char way; cin >> way;
			ways[i] = way == 'L';
			int K; cin >> K;
			for (int j = 0; j < K; ++j) {
				char ch; cin >> ch;
				ch_mp[ch] = i;

			}
		}
		int M; cin >> M;
		for (int i = 0; i < M; ++i) {
			string st; cin >> st;
			solve(st,ch_mp,ways);
		}
		if(t!=T-1)cout<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3152
final_rank: 13

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
 
using namespace std;
 
#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
 
template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }
 
typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Node{
  char value;
  Node* child[2];
  Node() { memset(child, 0, sizeof(child)); }
  Node(char c) : value(c) { memset(child, 0, sizeof(child)); }
};
struct Result{
  Node* n;
  int p;
  Result(){}
  Result(Node* n, int p) : n(n), p(p) {}
};
int G;
map<char, int> ope_d;
char type[100];
bool is_ope(char c){
  return ope_d.count(c);
}
Result expr(const string& s, int p, int depth){
  //printf("p = %d depth = %d s[p] = %c\n", p, depth, s[p]);
  if(depth == G){
    if(s[p] == '('){
      Result r = expr(s, p + 1, 0);
      assert(s[r.p] == ')');
      r.p++;
      return r;
    }else if(isalpha(s[p])){
      Node* n = new Node(s[p]);
      return Result(n, p + 1);
    }else{
      assert(false);
    }
  }else{
    if(type[depth] == 'L'){
      Result r = expr(s, p, depth + 1);
      while(is_ope(s[r.p]) && ope_d[s[r.p]] == depth){
        Node* n = new Node(s[r.p]);
        Result r_ = expr(s, r.p + 1, depth + 1);
        n->child[0] = r.n;
        n->child[1] = r_.n;
        r.n = n;
        r.p = r_.p;
      }
      return r;
    }else if(type[depth] == 'R'){
      Result r = expr(s, p, depth + 1);
      if(is_ope(s[r.p]) && ope_d[s[r.p]] == depth){
        Result r_ = expr(s, r.p + 1, depth);
        Node* n = new Node(s[r.p]);
        n->child[0] = r.n;
        n->child[1] = r_.n;
        r.n = n;
        r.p = r_.p;
      }
      return r;
    }else{
      assert(false);
    }
  }
}
void print(Node* p){
  assert(p);
  if(isalpha(p->value)){
    assert(!p->child[0]);
 
    putchar(p->value);
  }else{
    assert(p->child[0]);
 
    putchar('(');
    print(p->child[0]);
    putchar(p->value);
    print(p->child[1]);
    putchar(')');
  }
}
int main(){
  int D;
  cin >> D;
  bool first = true;
  while(D--){
    if(first) first = false;
    else cout << endl;
 
    cin >> G;
    REP(i, G){
      cin >> type[i];
      int T; cin >> T;
      while(T--){
        char ope; cin >> ope;
        ope_d[ope] = i;
      }
    }
    int N; cin >> N;
    REP(i, N){
      string s;
      cin >> s;
      Result r = expr(s, 0, 0);
      print(r.n);
      cout << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8644
final_rank: 19

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

int G;
set<char> g[128];
char D[128];
int p;
string e;

string f(int l){
	if( G == l ){
		if( e[p] == '(' ){
			p++;
			string r = f(0);
			p++;
			return r;
		}else{
			string r = string(1,e[p]);
			p++;
			return r;
		}
	}
	string le = f(l+1);
	vector<string> seq;
	seq.push_back(le);
	while( g[l].count(e[p]) ){
		char op = e[p];
		seq.push_back(string(1,op));
		p++;
		seq.push_back(f(l+1));
	}
	if( D[l] == 'L' ){
		string res = seq[0];
		for(int i = 1 ; i < seq.size() ; i+=2)
			res = "(" + res + seq[i] + seq[i+1] + ")";
		return res;
	}else{
		string res = seq[seq.size()-1];
		for(int i = seq.size()-2 ; i >= 0 ; i-= 2)
			res = "(" + seq[i-1] + seq[i] + res + ")";
		return res;
	}
}
int main(){
	int T;
	cin >> T;
	int cnt = 0;
	while(T--){
		if( cnt++ ) cout << endl;
		for(int i = 0 ; i < 128 ; i++) g[i].clear();
		cin >> G;
		for(int i = 0 ; i < G ; i++){
			cin >> D[i];
			int M;
			cin >> M;
			for(int j = 0 ; j < M ; j++){
				char c;
				cin >> c;
				g[i].insert(c);
			}
		}
		int Q;
		cin >> Q;
		for(int i = 0 ; i < Q ; i++){
			cin >> e;
			p = 0;
			cout << f(0) << endl;
		}
		
		
	}
}
accuracy: 1
time_ms: 70
memory_kb: 1292
final_rank: 8

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_GN = 20;

/* typedef */

typedef deque<string> dqst;

enum { ASC_L, ASC_R };

/* global variables */

int gn;
int chgrp[256], ascs[MAX_GN];

/* subroutines */

string expr(string& str, int& pos, int pv) {
  if (pv >= gn) {
    if (str[pos] == '(') {
      pos++;
      string res = expr(str, pos, 0);
      pos++;
      return res;
    }

    return string(1, str[pos++]);
  }

  dqst q;
  q.push_back(expr(str, pos, pv + 1));

  while (chgrp[str[pos]] == pv) {
    //if (str[pos] == '/')
    //printf("pos=%d, str[pos]=%c, pv=%d\n", pos, str[pos], pv);
    q.push_back(string(1, str[pos++]));
    q.push_back(expr(str, pos, pv + 1));
  }

  string exp0;
  if (ascs[pv] == ASC_L) {
    exp0 = q.front(); q.pop_front();

    while (! q.empty()) {
      string op = q.front(); q.pop_front();
      string exp1 = q.front(); q.pop_front();
      exp0 = "(" + exp0 + op + exp1 + ")";
    }
  }
  else {
    exp0 = q.back(); q.pop_back();

    while (! q.empty()) {
      string op = q.back(); q.pop_back();
      string exp1 = q.back(); q.pop_back();
      exp0 = "(" + exp1 + op + exp0 + ")";
    }
  }

  return exp0;
}

/* main */

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

  for (bool first = true; tn--; first = false) {
    if (! first) cout << endl;

    memset(chgrp, -1, sizeof(chgrp));

    cin >> gn;
    for (int i = 0; i < gn; i++) {
      char lr;
      int m;
      cin >> lr >> m;
      ascs[i] = (lr == 'L') ? ASC_L : ASC_R;

      for (int j = 0; j < m; j++) {
	char op;
	cin >> op;
	chgrp[op] = i;
      }
    }

    int n;
    cin >> n;

    for (int i = 0; i < n; i++) {
      string str;
      cin >> str;

      int pos = 0;
      cout << expr(str, pos, 0) << endl;
    }
  }

  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 1412
final_rank: 11

code_snippet: #include<stdio.h>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
int cur;
char ch[1010];
char in[3];
char op[20]="+-*/<>=&|^";
int rn[20];
char str[110];
int n;
string emp="";
string solve(int a){
	if(a==n){
		if(str[cur]=='('){
			cur++;
			string ret=solve(0);
			int now=0;
			bool ok=false;
			for(int i=0;i<ret.size()-1;i++){
				if(ret[i]=='(')now++;
				if(ret[i]==')')now--;
				if(now==0)ok=true;
			}
			cur++;
	//		printf("%d %d: %s\n",a,cur,ret.c_str());
			if(ok)return "("+ret+")";
			return ret;
		}else{
			cur++;
		//	printf("%d %d: %c\n",a,cur,str[cur-1]);
			return emp+str[cur-1];
		}
	}
	if(ch[a]=='L'){
		string ret=solve(a+1);
		while(1){
			bool ok=false;
			for(int i=0;i<10;i++)if(str[cur]==op[i]&&rn[i]==a)ok=true;
			if(!ok)break;
			char ad=str[cur];
			cur++;
			string tmp=solve(a+1);
			ok=false;
			int now=0;
			for(int i=0;i<ret.size()-1;i++){
				if(ret[i]=='(')now++;
				if(ret[i]==')')now--;
				if(now==0)ok=true;
			}
			if(ok)ret="("+ret+")";
			ok=false;
			now=0;
			for(int i=0;i<tmp.size()-1;i++){
				if(tmp[i]=='(')now++;
				if(tmp[i]==')')now--;
				if(now==0)ok=true;
			}
			if(ok)tmp="("+tmp+")";
			ret=ret+ad+tmp;
		}
		//printf("%d %d: %s\n",a,cur,ret.c_str());
		return ret;
	}else{
		stack<string>S;
		S.push(solve(a+1));
		stack<char>os;
		while(1){
			bool ok=false;
			for(int i=0;i<10;i++)if(str[cur]==op[i]&&rn[i]==a)ok=true;
			if(!ok)break;
			os.push(str[cur]);
			cur++;
			string tmp=solve(a+1);
			S.push(tmp);
		}
		string ret=S.top();
		S.pop();
		while(S.size()){
			string L=S.top();
			bool ok=false;
			int now=0;
			for(int i=0;i<L.size()-1;i++){
				if(L[i]=='(')now++;
				if(L[i]==')')now--;
				if(now==0)ok=true;
			}
			if(ok)L="("+L+")";
			ok=false;now=0;
			for(int i=0;i<ret.size()-1;i++){
				if(ret[i]=='(')now++;
				if(ret[i]==')')now--;
				if(now==0)ok=true;
			}
			if(ok)ret="("+ret+")";
			ret=L+os.top()+ret;
			S.pop();os.pop();
		}
		//printf("%d %d: %s\n",a,cur,ret.c_str());
		return ret;
	}
}
int main(){
	int T;scanf("%d",&T);
	bool bl=false;
	while(T--){
		if(bl)printf("\n");
		bl=true;
		int a;scanf("%d",&a);
		n=a;
		for(int i=0;i<a;i++){
			int p;
			scanf("%s%d",ch+i,&p);
			for(int j=0;j<p;j++){
				scanf("%s",in);
				for(int k=0;k<10;k++)if(in[0]==op[k])rn[k]=i;
			}
		}
		int b;scanf("%d",&b);
		for(int i=0;i<b;i++){
			cur=0;scanf("%s",str);
			string ret=solve(0);
			bool ok=false;
			int now=0;
			for(int j=0;j<ret.size()-1;j++){
				if(ret[j]=='(')now++;
				if(ret[j]==')')now--;
				if(now==0)ok=true;
			}
			if(ok)ret="("+ret+")";
			printf("%s\n",ret.c_str());
		}
	}
}
accuracy: 1
time_ms: 90
memory_kb: 1272
final_rank: 12

code_snippet: #include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;

constexpr int MAX = 10;

char A[MAX];
int M[MAX];
int priority[128];

int g;
string expression;

string parse(int p, int l, int r) {
	if(p == g) {
		if(expression[l] == '(') return parse(0, l + 1, r - 1);
		return expression.substr(l, r - l);
	}

	int start = l, end = r, inc = 1, l_p = p + 1, r_p = p;
	if(A[p] == 'L') {
		start = r - 1;
		end = l - 1;
		inc = -1;
		swap(l_p, r_p);
	}

	int cnt = 0;
	for(int i = start; i != end; i += inc) {
		if(!cnt && priority[expression[i]] == p) {
			return '(' + parse(l_p, l, i) + expression[i] + parse(r_p, i + 1, r) + ')';
		}
		if(expression[i] == '(') ++cnt;
		else if(expression[i] == ')') --cnt;
	}

	return parse(p + 1, l, r);
}

void solve() {
	cin >> g;

	for(int i = 0; i < g; ++i) {
		cin >> A[i] >> M[i];
		for(int j = 0; j < M[i]; ++j) {
			char c;
			cin >> c;
			priority[c] = i;
		}
	}

	int n;
	cin >> n;
	while(n--) {
		cin >> expression;
		cout << parse(0, 0, expression.size()) << endl;
	}
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	int t;
	cin >> t;
	while(t--) {
		memset(priority, -1, sizeof(priority));
		solve();
		if(t) cout << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1268
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<cassert>
#include<deque>
#include<sstream>
#include<map>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(_,n) REP(_,0,n)
#define F first
#define S second
using namespace std;
typedef pair<string,int> si;
vector<vector<char> > op;
vector<char> dir;
string line;
int size;
int T,G,N;
vector<map<char,bool> > vmcb;

string cnuf(vector<string> &vec)
{
  //cout << "-----------cnuf--------------" << endl;
  //rep(i,vec.size())cout << "vec : " << vec[i] << endl;
  int n = vec.size();
  for(int i=G-1;i>=0;i--)
    {
      if(dir[i] == 'L')
	{
	  for(int j=1;j<n;j+=2)
	    {
	      //cerr << "opera = "  << vec[j] << endl;
	      assert(vec[j].size() == 1);
	      if(vmcb[i][vec[j][0]])
		{
		  vector<string> vesc;
		  string compo = "(";
		  rep(k,n)
		    {
		      if(k+1 == j || k-1 == j || k == j)
			{
			  if(k-1 == j)
			    {
			      compo += vec[k]+")";
			      vesc.push_back(compo);
			      continue;
			    }
			  else if(k+1 == j)
			    {
			      compo += vec[k];
			      continue;
			    }
			  else
			    {
			      compo += vec[k];
			      continue;
			    }
			}
		      else
			vesc.push_back(vec[k]);
		    }
		  return cnuf(vesc);
		}
	    }
	}
      else if(dir[i] == 'R')
	{	  
	  int st = vec.size()-1;
	  if(st%2 == 0)st--;
	   
	  for(int j=st;j>=0;j-=2)
	    {
	      assert(vec[j].size() == 1);
	      if(vmcb[i][vec[j][0]])
		{
		  vector<string> vesc;
		  string compo = "(";
		  rep(k,n)
		    {
		      if(k+1 == j || k-1 == j || k == j)
			{
			  if(k-1 == j)
			    {
			      compo += vec[k]+")";
			      vesc.push_back(compo);
			      continue;
			    }
			  else if(k+1 == j)
			    {
			      compo += vec[k];
			      continue;
			    }
			  else
			    {
			      compo += vec[k];
			      continue;
			    }
			}
		      else
			vesc.push_back(vec[k]);
		    }
		  return cnuf(vesc);
		}
	    }
	}


    }
  string ret;
  rep(i,vec.size())ret += vec[i];
  return ret;
}

si func(int p)
{
  vector<string> vec;
  //cout << "fuc : "<< line.substr(p,line.size()-p) << endl;
  int j=p;
  REP(i,p,size)
    {
      if(line[i] == ')')
	{
	  if(i-p == 3)
	    {
	      //cout << "end func ret : " << "(" << line.substr(p,3) << ")" << endl;
	      return si("("+line.substr(p,3)+")",i);	
	    }
	  break;
	}
      else if(line[i] == '(')
	{
	  si SI = func(i+1);
	  vec.push_back("("+SI.F+")");
	  i = SI.S;
	  j = i+1;
	  //cout << "p = " << p << " i = " << i << endl;
	  continue;
	}
      j++;
      vec.push_back(line.substr(i,1));
    }
  //cout << "pre end;" << endl;
  //rep(i,vec.size())cout << vec[i] << endl;
  //cout << "end func : " << endl;
  return si(cnuf(vec),j);
}

string Remove(string s)
{
  //cout << "Remove : " << s << endl;
  rep(i,s.size())
    {
      //cout << "i = " << i << " : " << s << endl;
      if(s[i] != '(')continue;

      int cnt = 0;
      bool ok = false;
      REP(j,i,s.size())
	{
	  if(s[j] == '(')cnt++;
	  else if(s[j] == ')')cnt--;
	  if(cnt == 0)
	    {
	      //cout << s[i] << " " << s[j] << endl; 
	      if(!ok)
		{
		  s[i] = ' ';
		  s[j] = ' ';
		}
	      break;
	    }
	  if(cnt == 1 && (s[j] == '+' || s[j] == '-' || s[j] == '*' || s[j] == '/' || s[j] == '<' || s[j] == '>' || s[j] == '=' || s[j] == '&' || s[j] == '|' || s[j] == '^'))ok = true;
	}
    }
  stringstream ss;
  ss << s;
  string ret;
  while(!(ss >> s).fail())ret += s;
  return ret;
}

int main()
{

  cin >> T;
  bool f = false;
  while(T-- > 0)
    {
      if(f)cout << endl;
      if(!f)f = true;
      cin >> G;
      op.clear();
      dir.clear();
      vmcb.clear();
      op.resize(G);
      dir.resize(G);
      vmcb.resize(G);

      rep(i,G)
	{
	  cin >> dir[i];
	  int n;
	  cin >> n;
	  rep(j,n)
	    {
	      char opera;
	      cin >> opera;
	      op[i].push_back(opera);
	      vmcb[i][opera] = true; 
	    }
	}


      vector<string> vec;
      cin >> N;
      cin.ignore();
      rep(_,N)
	{
	 
	  getline(cin,line);
	  //cout << "LINE : " << line << endl;
	  line = "(" + line + ")";
	  size = line.size();
	  cout << Remove(func(1).F) << endl;
	}
    }
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 1376
final_rank: 17

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

const int OpeSize = 15;

struct data{
  char ope,dir;
};

vector<data> V[OpeSize];

void input(){

  for(int i = 0; i < OpeSize; i++) V[i].clear();

  int n;
  cin >> n;
  for(int i = 0; i < n; i++){
    char d;
    int num;
    cin >> d;
    cin >> num;
    while(num--){
      char ope;
      cin >> ope;
      V[i].push_back((data){ope,d});
    }
  }
}

bool isVar(const string& s){
  if(s.length() != 1) return false;
  return 'a' <= s[0] && s[0] <= 'z';
}

string rmPara(string s){
  if(s[0] != '(' || s[s.length()-1] != ')') return s;

  int p = 0;
  for(int i = 0; i < (int)s.length()-1; i++){
    if(s[i] == '(') p++;
    if(s[i] == ')') p--;
    if(p == 0) return s;
  }
  return s.substr(1,s.length()-2);
}

bool match(const vector<data>& v, const char c){
  for(int i = 0; i < (int)v.size(); i++)
    if(v[i].ope == c) return true;
  return false;
}

int find(const vector<data>& v, const string& s){
  int p = 0;

  if(v[0].dir == 'L'){
    for(int i = s.length()-1; i >= 0; i--){
      if(s[i] == '(') p++;
      if(s[i] == ')') p--;
      if(p == 0 && match(v,s[i])) return i;
    }
  }else{
    for(int i = 0; i < (int)s.length(); i++){
      if(s[i] == '(') p++;
      if(s[i] == ')') p--;
      if(p == 0 && match(v,s[i])) return i;
    }
  }
  return -1;
}

string parse(string s){

  s = rmPara(s);
 
  if(isVar(s)){
    return s;
  }else{
    //Expr Op Expr
    
    for(int i = 0; i < OpeSize; i++){
      if(V[i].empty()) continue;
      int pos = find(V[i],s);
      if(pos != -1){
	return "(" + parse(s.substr(0,pos)) + s[pos]  + parse(s.substr(pos+1)) + ")";
      }
    }
  }
  return parse(s);
}

int main(){
  
  int T;
  cin >> T;
  while(T--){
    input();
    int N;
    cin >> N;
    while(N--){
      string s;
      cin >> s;
      cout << parse(s) << endl;
    }
    if(T > 0) cout << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 1244
final_rank: 10

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Node{
  char value;
  Node* child[2];
  Node() { memset(child, 0, sizeof(child)); }
  Node(char c) : value(c) { memset(child, 0, sizeof(child)); }
};
struct Result{
  Node* n;
  int p;
  Result(){}
  Result(Node* n, int p) : n(n), p(p) {}
};
int G;
map<char, int> ope_d;
char type[100];
bool is_ope(char c){
  return ope_d.count(c);
}
Result expr(const string& s, int p, int depth){
  //printf("p = %d depth = %d s[p] = %c\n", p, depth, s[p]);
  if(depth == G){
    if(s[p] == '('){
      Result r = expr(s, p + 1, 0);
      assert(s[r.p] == ')');
      r.p++;
      return r;
    }else if(isalpha(s[p])){
      Node* n = new Node(s[p]);
      return Result(n, p + 1);
    }else{
      assert(false);
    }
  }else{
    if(type[depth] == 'L'){
      Result r = expr(s, p, depth + 1);
      while(is_ope(s[r.p]) && ope_d[s[r.p]] == depth){
        Node* n = new Node(s[r.p]);
        Result r_ = expr(s, r.p + 1, depth + 1);
        n->child[0] = r.n;
        n->child[1] = r_.n;
        r.n = n;
        r.p = r_.p;
      }
      return r;
    }else if(type[depth] == 'R'){
      Result r = expr(s, p, depth + 1);
      if(is_ope(s[r.p]) && ope_d[s[r.p]] == depth){
        Result r_ = expr(s, r.p + 1, depth);
        Node* n = new Node(s[r.p]);
        n->child[0] = r.n;
        n->child[1] = r_.n;
        r.n = n;
        r.p = r_.p;
      }
      return r;
    }else{
      assert(false);
    }
  }
}
void print(Node* p){
  assert(p);
  if(isalpha(p->value)){
    assert(!p->child[0]);

    putchar(p->value);
  }else{
    assert(p->child[0]);

    putchar('(');
    print(p->child[0]);
    putchar(p->value);
    print(p->child[1]);
    putchar(')');
  }
}
int main(){
  int D;
  cin >> D;
  bool first = true;
  while(D--){
    if(first) first = false;
    else cout << endl;

    cin >> G;
    REP(i, G){
      cin >> type[i];
      int T; cin >> T;
      while(T--){
        char ope; cin >> ope;
        ope_d[ope] = i;
      }
    }
    int N; cin >> N;
    REP(i, N){
      string s;
      cin >> s;
      Result r = expr(s, 0, 0);
      print(r.n);
      cout << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 6744
final_rank: 18

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

int g;
int prior[128];
int lft[16];
string s;
int pos;

void expr(int pr, deque<char> &res){
	if( pr == g ){
		if( s[pos] == '(' ){
			++pos;
			expr(0, res);
			++pos;
		}
		else{
			res.push_back( s[pos] );
			++pos;
		}
	}
	else{
		deque<char> dq;

		expr(pr + 1, dq);

		while( prior[s[pos]] == pr ){
			dq.push_front('(');
			dq.push_back( s[pos] );
			++pos;
			expr(pr + lft[pr], dq);
			dq.push_back(')');
		}
		
		res.insert( res.end(), dq.begin(), dq.end() );
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int d, m, n;
	char a, p;
	
	prior['('] = prior[')'] = -1;
	
	cin >> d;
	while( d-- ){
		cin >> g;
		for(int i = 0; i < g; ++i){
			cin >> a >> m;
			lft[i] = (a == 'L');
			
			for(int j = 0; j < m; ++j){
				cin >> p;
				prior[p] = i;
			}
		}
		
		cin >> n;
		for(int i = 0; i < n; ++i){
			cin >> s;
			s = '(' + s + ')';
			pos = 0;
			deque<char> res;
			expr(g, res);
			cout << string(res.begin(), res.end()) << '\n';
		}
		
		if( d ) cout << '\n';
	}
}
accuracy: 1
time_ms: 50
memory_kb: 1344
final_rank: 5

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

int g;
int prior[128];
int lft[16];
string s;
int pos;

void expr(int pr, deque<char> &res){
	if( pr == g ){
		if( s[pos] == '(' ){
			++pos;
			expr(0, res);
			++pos;
		}
		else{
			res.push_back( s[pos] );
			++pos;
		}
	}
	else{
		deque<char> dq;

		expr(pr + 1, dq);

		while( prior[s[pos]] == pr ){
			dq.push_front('(');
			dq.push_back( s[pos] );
			++pos;
			expr(pr + lft[pr], dq);
			dq.push_back(')');
		}
		
		res.insert( res.end(), dq.begin(), dq.end() );
	}
}

int main(){
	int d, m, n;
	char a, p;
	
	prior['('] = prior[')'] = -1;
	
	cin >> d;
	while( d-- ){
		cin >> g;
		for(int i = 0; i < g; ++i){
			cin >> a >> m;
			lft[i] = (a == 'L');
			
			for(int j = 0; j < m; ++j){
				cin >> p;
				prior[p] = i;
			}
		}
		
		cin >> n;
		for(int i = 0; i < n; ++i){
			cin >> s;
			s = '(' + s + ')';
			pos = 0;
			deque<char> res;
			expr(g, res);
			cout << string(res.begin(), res.end()) << '\n';
		}
		
		if( d ) cout << '\n';
	}
}
accuracy: 1
time_ms: 50
memory_kb: 1332
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <stack>
#include <cctype>

#define rep(i,n)    for(int i=0;i<n;++i)

using namespace std;

struct expr
{
	char c;
	bool is_op;
	expr *x, *y;

	expr(char c)
		: c(c), is_op(false), x(NULL), y(NULL)
	{
	}

	expr(char op, expr *x, expr *y)
		: c(op), is_op(true), x(x), y(y)
	{
	}

	~expr()
	{
		delete x;
		delete y;
	}

	string to_string()
	{
		stringstream buf;
		if (is_op)
			buf << "(" << x->to_string() << c << y->to_string() << ")";
		else
			buf << c;
		return buf.str();
	}
};

string src;
int p;

bool end() { return p >= src.length(); }
char peek() { return src[p]; }
void succ() { if (!end()) ++p; }

bool is_lassoc[11];
int prec[128]; // 値が大きい方が結合が強い

// op が来た時、op0 を reduce するか？
bool reduce(char op, char op0)
{
	return prec[op] < prec[op0] || (is_lassoc[prec[op0]] && prec[op] == prec[op0]);
}

expr *parse()
{
	stack<char> ost;
	stack<expr *> est;

	while (!end())
	{
		char c = peek();
		if (c == ')') break;
		if (isalpha(c))
		{
			succ();
			est.push(new expr(c));
		}
		else if (c == '(')
		{
			succ();
			est.push(parse());
			if (peek() == ')') succ();
		}
		else
		{
			succ();
			while (!ost.empty() && reduce(c, ost.top()))
			{
				expr *y = est.top(); est.pop();
				expr *x = est.top(); est.pop();
				est.push(new expr(ost.top(), x, y));
				ost.pop();
			}
			ost.push(c);
		}
	}
	while (!ost.empty())
	{
		expr *y = est.top(); est.pop();
		expr *x = est.top(); est.pop();
		est.push(new expr(ost.top(), x, y));
		ost.pop();
	}
	return est.top();
}

int main()
{
	int D;
	cin>>D;
	while(D--)
	{
		int G;
		cin>>G;
		rep(i,G)
		{
			char A;
			int M;
			cin>>A>>M;
			is_lassoc[i] = A == 'L';
			rep(j,M)
			{
				char op;
				cin>>op;
				prec[op] = i;
			}
		}

		int N;
		cin>>N;
		rep(i,N)
		{
			cin>>src;
			p = 0;
			expr *e = parse();
			cout << e->to_string() << endl;
			delete e;
		}

		if (D) cout << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 1000
final_rank: 20

code_snippet: #include <iostream>
#include <string>
#include <vector>

using namespace std;
struct Rule {
	bool rightAssoc;
	string operators;
};
vector<Rule> g_rules;

struct Node {
	char op;
	Node *left, *right;
	Node(char o, Node *l = NULL, Node *r = NULL) :
		op(o), left(l), right(r)
	{ }
};

struct Result {
	int p;
	Node *v;
};

Result expr(int depth, const string &s, int p);
Result factor(const string &s, int p);
Result var(const string &s, int p);

Result expr(int depth, const string &s, int p){
	if(depth == g_rules.size()){ return factor(s, p); }
	Rule &rule = g_rules[depth];
	Result r = expr(depth + 1, s, p);
	Node *rmost = NULL;
	bool first = true;
	while(rule.operators.find(s[r.p]) != string::npos){
		Result q = expr(depth + 1, s, r.p + 1);
		if(rule.rightAssoc && first){
			Node *node = new Node(s[r.p], r.v, q.v);
			r.v = rmost = node;
			first = false;
		}else if(rule.rightAssoc){
			Node *node = new Node(s[r.p], rmost->right, q.v);
			rmost->right = node;
			rmost = rmost->right;
		}else{
			r.v = new Node(s[r.p], r.v, q.v);
		}
		r.p = q.p;
	}
	return r;
}
Result factor(const string &s, int p){
	Result r;
	if(s[p] == '('){
		r = expr(0, s, ++p);
		++r.p;
	}else{
		r = var(s, p);
	}
	return r;
}
Result var(const string &s, int p){
	Result r;
	r.v = new Node(s[p++]);
	r.p = p;
	return r;
}

void recur(Node *node){
	if(islower(node->op)){
		cout << node->op;
	}else{
		cout << "(";
		recur(node->left);
		cout << node->op;
		recur(node->right);
		cout << ")";
	}
	delete node;
}

int main(){
	int T;
	cin >> T;
	while(T--){
		int G;
		cin >> G;
		g_rules = vector<Rule>(G);
		for(int i = 0; i < G; ++i){
			string assoc, op;
			cin >> assoc;
			g_rules[i].rightAssoc = (assoc == "R");
			int opnum;
			cin >> opnum;
			while(opnum--){
				cin >> op;
				g_rules[i].operators.push_back(op[0]);
			}
		}
		int N;
		cin >> N;
		while(N--){
			string input;
			cin >> input;
			Result r = expr(0, input, 0);
			recur(r.v);
			cout << endl;
		}
		if(T != 0){ cout << endl; }
	}
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 932
final_rank: 3

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <stack>
#include <utility>
#include <cctype>
using namespace std;


string expr;
map<char,int> m_op;
bool op_left[100];

string postfix;
int child[100][2];

int pos;


int find_child( int k ){
	--pos;
	if( !isalpha( postfix[k] ) ){
		child[k][1] = find_child( pos );
		child[k][0] = find_child( pos );
	}

	return k;
}


void to_infix( int k ){
	if( isalpha( postfix[k] ) ){
		cout << postfix[k];
	}
	else{
		cout << '(';
		to_infix( child[k][0] );
		cout << postfix[k];
		to_infix( child[k][1] );
		cout << ')';
	}
}


void solve(){
	stack< pair<char,int> > st_op;
		//演算子と、優先度*2 を保持
	st_op.push( make_pair( '$', -999 ) );

	postfix.clear();

	for( int i = 0; i < expr.length(); ++i ){
		if( expr[i] == '(' ){
			st_op.push( make_pair( '(', -500 ) );
		}
		else if( expr[i] == ')' ){
			while( st_op.top().first != '(' ){
				postfix += st_op.top().first;
				st_op.pop();
			}
			st_op.pop();
		}
		else{
			map<char,int>::iterator it = m_op.find( expr[i] );

			if( it == m_op.end() ){
				postfix += expr[i];
			}
			else{
				int g = it->second;
				int g2 = g * 2 - op_left[g];
					//左結合なら優先度*2-1
					//右結合なら優先度*2(元と同じ)

				while( g2 < st_op.top().second ){
					postfix += st_op.top().first;
					st_op.pop();
				}

				st_op.push( make_pair( expr[i], g * 2 ) );
			}
		}
	}

	while( st_op.size() > 1 ){
		postfix += st_op.top().first;
		st_op.pop();
	}

	pos = postfix.length() - 1;
	find_child( pos );
	
	to_infix( postfix.length() - 1 );
	cout << endl;
}


int main(){
	postfix.reserve( 100 );

	int D;
	cin >> D;
	for( int d = 0; d < D; ++d ){
		if( d != 0 ) cout << '\n';

		m_op.clear();
		
		int G;
		cin >> G;
		for( int g = 0; g < G; ++g ){
			char join, op;
			int M;
			cin >> join >> M;
			op_left[g] = ( join == 'L' );
			for( int m = 0; m < M; ++m ){
				cin >> op;
				m_op.insert( make_pair( op, g ) );
			}
		}

		int N;
		cin >> N;
		for( int n = 0; n < N; ++n ){
			cin >> expr;
			solve();

		}
	}
}
accuracy: 1
time_ms: 50
memory_kb: 920
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

vector<vector<char> > g;
vector<bool> type;           // 0:L 1:R

string parse(const string &s) {
  REP(i, g.size()) {
    int start = 0, end = s.size(), d = 1;
    if (type[i]==0) start = s.size()-1, end = 0, d = -1;
    int a = 0;
    for (int j=start; j!=end; j+=d) {
      if (s[j] == '(') a++;
      else if(s[j] == ')') a--;
      else if (a==0) {
        FOR(it, g[i]) {
          if (s[j] == *it)
            return "("+ parse(s.substr(0,j)) + string(1,*it) + parse(s.substr(j+1)) + ")";
        }
      }
    }
  }
  if (s[0] == '(') {
    return parse(s.substr(1,s.size()-2));
  }
  return s;
}

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

  REP(t,T) {
    if (t) cout << endl;
    int G;cin >> G;
    g.resize(G);
    type.clear();
    REP(i,G) {
      char A; cin >> A;
      int M; cin >> M;
      type.push_back(A=='R');
      vector<char> tmp(M);
      REP(j,M) cin>>tmp[j];
      //g[G-i-1] = tmp;
      g[i] = tmp;
    }
    int n;cin >> n;
    REP(i,n) {
      string e;
      cin >> e;
      cout << parse(e) << endl;
    }
  }
  
  
}
accuracy: 1
time_ms: 130
memory_kb: 928
final_rank: 14