#include using namespace std; struct UnionFind { int N; vector parents; vector zeros; vector ones; long long ans; UnionFind(const vector& A) { N = A.size(); parents.assign(N, -1); zeros = vector(A.begin(), A.end()); ones.assign(N, 1); ans = 0; } int find(int x) { if (parents[x] < 0) return x; vector st; while (parents[x] >= 0) { st.push_back(x); x = parents[x]; } for (int y : st) parents[y] = x; return x; } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) return; parents[x] += parents[y]; parents[y] = x; ans += ones[x] * zeros[y]; zeros[x] += zeros[y]; ones[x] += ones[y]; } int size(int x) { return -parents[find(x)]; } bool same(int x, int y) { return find(x) == find(y); } }; int main() { int N; cin >> N; string S; cin >> S; vector A(N + 1); A[0] = 0; for (int i = 1; i <= N; ++i) cin >> A[i]; UnionFind uf(A); vector stack = {0}; vector parent(N + 1, -1); int next_idx = 1; for (int i = 0; i < 2 * N; ++i) { if (S[i] == '(') { parent[next_idx] = stack.back(); stack.push_back(next_idx++); } else { stack.pop_back(); } } // 優先度付きキュー (最大ヒープ) using T = pair; priority_queue pq; for (int i = 0; i <= N; ++i) { pq.emplace((double)(-A[i]), i); } while (!pq.empty()) { auto [value, idx] = pq.top(); pq.pop(); int rep = uf.find(idx); double current_value = -(double)uf.zeros[rep] / uf.ones[rep]; if (value != current_value) continue; uf.unite(uf.find(parent[rep]), rep); int new_head = uf.find(rep); if (new_head != 0) { double new_val = -(double)uf.zeros[new_head] / uf.ones[new_head]; pq.emplace(new_val, new_head); } } cout << uf.ans << endl; return 0; }