#include #define endl '\n' using namespace std; int A, B, M, D, H; int n; int prices[30]; string s; string char_to_string(char c) { string t; t += c; return t; } vector solve_1() { vector v; int letters[300] = {0}; int k = 0; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; } } map mp; v.push_back(to_string(k)); v.push_back(char_to_string(s[0])); int tmp = 0; mp[s[0]] = 1; letters[s[0]] = 0; ++tmp; for (int i = 0; i < 300; i++) { if (letters[i]) { v.push_back(char_to_string(i)); letters[i] = ++tmp; mp[i] = tmp; } } int prev_deque = -1; int cnt = 0; int prev_sz = v.size(); for (int i = 0; i < n; i++) { if (mp[s[i]] != prev_deque) { if (i) v.push_back("w " + to_string(cnt)); if (i) v.push_back("cd " + to_string(mp[s[i]])); prev_deque = mp[s[i]]; cnt = 0; } cnt++; } v.push_back("w " + to_string(cnt)); v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } vector solve_1_1() { vector v; int letters[300] = {0}; int k = 0; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; } } map mp; v.push_back(to_string(k)); int tmp = 0; for (int i = 0; i < 300; i++) { if (letters[i]) { v.push_back(char_to_string(i)); letters[i] = ++tmp; mp[i] = tmp; } } int prev_deque = -1; int cnt = 0; int prev_sz = v.size(); if (mp['_'] == 1) { v.push_back("push"); } v.push_back("cd " + to_string(mp[s[0]])); bool p = true; for (int i = 0; i < n; i++) { if (mp[s[i]] != prev_deque) { if (i && p) v.push_back("w " + to_string(cnt)); p = true; if (i) { if (s[i] == '_') { v.push_back("pop"); v.push_back("w 1"); if (A < B) v.push_back("cl"); else v.push_back("cr"); v.push_back("push"); p = false; cnt = 0; } else v.push_back("cd " + to_string(mp[s[i]])); } prev_deque = mp[s[i]]; cnt = 0; } cnt++; } if (p) v.push_back("w " + to_string(cnt)); v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } vector solve_2() { mt19937 mt(37); vector v; int letters[300] = {0}; int k = 0; string letts; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; letts += s[i]; } } map mp; v.push_back(to_string(1)); v.push_back(letts); int tmp = 0; mp[s[0]] = 1; letters[s[0]] = 0; ++tmp; int cnt = 0; int prev_sz = v.size(); int ind = 0; for (int i = 0; i < n; ) { int steps = letts.find(s[i]); if (steps < ind) { steps += ind; } else steps -= ind; int priceL = (steps - 1) * A; int priceR = (k - steps + 1) * B; if (priceL < priceR) { while (letts[ind] != s[i]) { v.push_back("cl"); ind++; if (ind == k) ind = 0; } } else { while (letts[ind] != s[i]) { v.push_back("cr"); ind--; if (ind == -1) ind = k-1; } } int cnt = 0; while (i < n && s[i] == letts[ind]) { ind++; i++; cnt++; if (ind == k) ind = 0; } v.push_back("w " + to_string(cnt)); } v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } mt19937 mt(137); vector solve_2_2() { vector v; int letters[300] = {0}; int k = 0; string letts; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; letts += s[i]; } } shuffle(letts.begin(), letts.end(), mt); // cerr << letts << endl; map mp; v.push_back(to_string(1)); v.push_back(letts); int tmp = 0; mp[s[0]] = 1; letters[s[0]] = 0; ++tmp; int cnt = 0; int prev_sz = v.size(); int ind = 0; for (int i = 0; i < n; ) { int steps = letts.find(s[i]); if (steps < ind) { steps += ind; } else steps -= ind; int priceL = (steps - 1) * A; int priceR = (k - steps + 1) * B; if (priceL < priceR) { while (letts[ind] != s[i]) { v.push_back("cl"); ind++; if (ind == k) ind = 0; } } else { while (letts[ind] != s[i]) { v.push_back("cr"); ind--; if (ind == -1) ind = k-1; } } int cnt = 0; while (i < n && s[i] == letts[ind]) { ind++; i++; cnt++; if (ind == k) ind = 0; } v.push_back("w " + to_string(cnt)); } v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } vector solve_2_2_2() { mt19937 rand(37); vector v; int letters[300] = {0}; int k = 0; string letts; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; letts += s[i]; } } map mp; v.push_back(to_string(1)); v.push_back(letts); int tmp = 0; mp[s[0]] = 1; letters[s[0]] = 0; ++tmp; int cnt = 0; int prev_sz = v.size(); int ind = 0; for (int i = 0; i < n; ) { int k = letts.size(); int find_ind = letts.find(s[i]); int steps_left; int steps_right; if (ind == find_ind) steps_left = 0, steps_right = 0; else if (ind < find_ind) { steps_left = find_ind - ind; steps_right = k + ind - find_ind; } else { steps_left = k - ind + find_ind; steps_right = ind - find_ind; } int priceL = steps_left * A; int priceR = steps_right * B; if (priceL < priceR) { while (letts[ind] != s[i]) { v.push_back("cl"); ind++; if (ind == k) ind = 0; } } else { while (letts[ind] != s[i]) { v.push_back("cr"); ind--; if (ind == -1) ind = k-1; } } int cnt = 0; while (i < n && s[i] == letts[ind]) { ind++; i++; cnt++; if (ind == k) ind = 0; } v.push_back("w " + to_string(cnt)); } v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } int min_price_seq = 1; int min_price = 2e9; vector solve_3() { vector v; vector seqs(min_price_seq); int letters[300] = {0}; int k = 0; string letts; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = ++k; letts += s[i]; } } if (letts.size() < min_price_seq) { return vector(); } int step = letts.size() / min_price_seq; for (int i = 0; i < min_price_seq - 1; i++) { seqs[i] = letts.substr(step * i, step); } seqs[min_price_seq - 1] = letts.substr(step * (min_price_seq-1), letts.size() - step * (min_price_seq-1)); v.push_back(to_string(min_price_seq)); for (int i = 0; i < min_price_seq; i++) { v.push_back(seqs[i]); } int tmp = 0; letters[s[0]] = 0; ++tmp; int cnt = 0; int prev_sz = v.size(); vector ind(min_price_seq, 0); int prev_seq = 0; for (int i = 0; i < n; ) { int curr = 0; for (int j = 0; j < min_price_seq; j++) { if (seqs[j].find(s[i]) != string::npos) { curr = j; break; } } if (curr != prev_seq) { v.push_back("cd " + to_string(curr + 1)); prev_seq = curr; } int k = seqs[curr].size(); int find_ind = seqs[curr].find(s[i]); int steps_left; int steps_right; if (ind[curr] == find_ind) steps_left = 0, steps_right = 0; else if (ind[curr] < find_ind) { steps_left = find_ind - ind[curr]; steps_right = k + ind[curr] - find_ind; } else { steps_left = k - ind[curr] + find_ind; steps_right = ind[curr] - find_ind; } int priceL = steps_left * A; int priceR = steps_right * B; if (priceL < priceR) { while (seqs[curr][ind[curr]] != s[i]) { v.push_back("cl"); ind[curr]++; if (ind[curr] == k) ind[curr] = 0; } } else { while (seqs[curr][ind[curr]] != s[i]) { v.push_back("cr"); ind[curr]--; if (ind[curr] == -1) ind[curr] = k-1; } } int cnt = 0; while (i < n && s[i] == seqs[curr][ind[curr]]) { ind[curr]++; i++; cnt++; if (ind[curr] == k) ind[curr] = 0; } v.push_back("w " + to_string(cnt)); } v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz)); return v; } long long best_price; vector solve(string letts, long long & curr_price, int n_seqs = min_price_seq, bool shuf = true) { vector v; vector seqs(n_seqs); int add_answer_size = 0; long long total_price = 0; int k = letts.size(); if (k < n_seqs) { curr_price = 1e18; return vector (); } if (shuf) shuffle(letts.begin(), letts.end(), mt); int step = k / n_seqs; int ip = 0; // cerr << "Letts: " << letts << endl; for (int i = 0; i < n_seqs - 1; i++) { int ic = 1 + mt()%(k - ip - n_seqs + i + 1); seqs[i] = letts.substr(ip, ic); // cerr << letts.substr(ip, ic) << endl;; ip += ic; } seqs[n_seqs - 1] = letts.substr(ip, k - ip); // for (int i = 0; i < n_seqs; i++) // { // seqs[i] = letts.substr(step * i, step); // } // // // for (int i = 0; i < k % n_seqs; i++) // { // seqs[i] += char_to_string(letts[n_seqs*step+i]); // } int seq_pos[300]; v.push_back(to_string(n_seqs)); total_price = prices[n_seqs]; for (int i = 0; i < n_seqs; i++) { v.push_back(seqs[i]); int seqs_sz = seqs[i].size(); for (int j = 0; j < seqs_sz; j++) seq_pos[seqs[i][j]] = i; } int tmp = 0; ++tmp; int cnt = 0; int prev_sz = v.size(); vector ind(n_seqs, 0); stack st; int prev_seq = 0; for (int i = 0; i < n; ) { if (total_price > best_price) { curr_price = total_price; return vector (); } int curr = 0; curr = seq_pos[s[i]]; if (curr != prev_seq && curr != -1) { v.push_back("cd " + to_string(curr + 1)); total_price += D; prev_seq = curr; } if (curr == -1) { curr = prev_seq; while (!st.empty() && st.top() != s[i] && 1) { v.push_back("pop"); total_price += H; seq_pos[st.top()] = prev_seq; seqs[prev_seq].insert(ind[curr], char_to_string(st.top())); st.pop(); if (total_price > best_price) { curr_price = total_price; return vector (); } } v.push_back("pop"); total_price += H; seq_pos[st.top()] = prev_seq; seqs[prev_seq].insert(ind[curr], char_to_string(st.top())); st.pop(); k = seqs[curr].size(); int cnt = 0; while (i < n && s[i] == seqs[curr][ind[curr]]) { ind[curr]++; i++; cnt++; if (ind[curr] == k) ind[curr] = 0; } v.push_back("w " + to_string(cnt)); for (int j = 1; j <= cnt; j++) { total_price += M / j; if (M / j == 0) total_price++; } continue; } int k = seqs[curr].size(); int find_ind = seqs[curr].find(s[i]); int steps_left; int steps_right; if (ind[curr] == find_ind) steps_left = 0, steps_right = 0; else if (ind[curr] < find_ind) { steps_left = find_ind - ind[curr]; steps_right = k + ind[curr] - find_ind; } else { steps_left = k - ind[curr] + find_ind; steps_right = ind[curr] - find_ind; } long long priceL = (long long)steps_left * A; long long priceR = (long long)steps_right * B; long long priceStack = (long long)steps_left * H * (1 + mt()%2); // if (priceStack < min(priceL, priceR) && steps_left) { while (seqs[curr][ind[curr]] != s[i]) { v.push_back("push"); total_price += H; st.push(seqs[curr][ind[curr]]); seq_pos[seqs[curr][ind[curr]]] = -1; seqs[curr].erase(ind[curr], 1); if (ind[curr] == seqs[curr].size()) ind[curr] = 0; if (total_price > best_price) { curr_price = total_price; return vector (); } } k = seqs[curr].size(); } else if (priceL < priceR && steps_left) { // total_price += priceL; // // // if (total_price > best_price) // { // curr_price = total_price; // return vector (); // } // // v.push_back("*" + to_string(steps_left) + " cl"); // ind[curr] = seqs[curr].find(s[i]); // // add_answer_size += steps_left - 1; int addl = 0; int sl = 0; while (seqs[curr][ind[curr]] != s[i]) { v.push_back("cl"); total_price += A; ind[curr]++; if (ind[curr] == k) ind[curr] = 0; if (total_price > best_price) { curr_price = total_price; return vector (); } sl++; addl += A; } // if (sl != steps_left) exit(1); // if (addl != priceL) exit(2); } else if (steps_left) { while (seqs[curr][ind[curr]] != s[i]) { v.push_back("cr"); total_price += B; ind[curr]--; if (ind[curr] == -1) ind[curr] = k-1; if (total_price > best_price) { curr_price = total_price; return vector (); } } } int cnt = 0; while (i < n && s[i] == seqs[curr][ind[curr]]) { ind[curr]++; i++; cnt++; if (ind[curr] == k) ind[curr] = 0; } v.push_back("w " + to_string(cnt)); for (int j = 1; j <= cnt; j++) { total_price += M / j; if (M / j == 0) total_price++; } } v.insert(v.begin() + prev_sz, to_string(v.size() - prev_sz + add_answer_size)); curr_price = total_price; return v; } void print_answer(vector v) { int sz = v.size(); for (int i = 0; i < sz; i++) { if (v[i][0] != '*') cout << v[i] << endl; else { // cerr << "---" << v[i] << endl; stringstream read(v[i].substr(1, v[i].size() - 1)); int cnt; read >> cnt; string command; read >> command; for (int j = 0; j < cnt; j++) cout << command << endl; } } } long long evalute(vector v) { if (v.empty()) { return 1e18; } stringstream readK(v[0]); int k; readK >> k; long long ret = prices[k]; int sz = v.size(); for (int i = k+2; i < sz; i++) { stringstream read(v[i]); string command; read >> command; if (command == "w") { int cnt; read >> cnt; for (int j = 1; j <= cnt; j++) { ret += M / j; } } else if (command == "cd") { ret += D; } else if (command == "cl") { ret += A; } else if (command == "cr") { ret += B; } else if (command == "push") { ret += H; } else if (command == "pop") { ret += H; } } return ret; } int main () { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); freopen("printing.in", "r", stdin); freopen("printing.out", "w", stdout); cin >> n; cin >> s; cin >> A >> B >> M >> D >> H; for (int i = 1; i <= 27; i++) { cin >> prices[i]; if (prices[i] < min_price) { min_price = prices[i]; min_price_seq = i; } } vector best_sol = solve_1(); best_price = evalute(best_sol); vector sol = solve_2(); long long curr_price = evalute(sol); if (curr_price < best_price) { best_price = curr_price; best_sol = sol; } sol = solve_3(); curr_price = evalute(sol); if (curr_price < best_price) { best_price = curr_price; best_sol = sol; } int br = 0; bool shuf = false; double prev_execution = 0; bool letters[300] = {0}; string letts; for (int i = 0; i < n; i++) { if (letters[s[i]] == 0) { letters[s[i]] = 1; letts += s[i]; } } int brLetters = letts.size(); while ((double)clock() / CLOCKS_PER_SEC + prev_execution < 4.8) { // cerr << (double)clock() / CLOCKS_PER_SEC << endl; clock_t st_time = clock(); if (br%brLetters == brLetters-1) br++; if (br > brLetters) shuf = true; long long curr_price = 0; vector sol = solve(letts, curr_price, br%27 + 1, shuf); if (curr_price < best_price) { best_price = curr_price; best_sol = sol; } // cerr << "============================\n"; prev_execution = (double)(clock() - st_time) / CLOCKS_PER_SEC; br++; } // cerr << "BR: " << br << endl; print_answer(best_sol); // cerr << best_price << endl; return 0; } /** 7 hellohi 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 7 hellohi 100 200 300 400 5 10 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 120 21 22 23 24 25 26 27 8 hellohi_ 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 120 21 22 23 24 25 26 27 */