Submission #761622

#TimeUsernameProblemLanguageResultExecution timeMemory
761622gun_ganZagrade (COI17_zagrade)C++17
100 / 100
241 ms124560 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MX = 3e5 + 5, inf = 1e9; int N; string s; vector<int> g[MX]; int par[MX], bal[MX]; set<pair<int, int>> path[MX][2]; // open, close // (balance, count) int find(int v) { return par[v] == v ? v : par[v] = find(par[v]); } ll ans = 0; void dfs(int v, int p) { for(auto u : g[v]) { if(u == p) continue; // build bal[u] = bal[v] + (s[u] == '(' ? 1 : -1); dfs(u, v); } for(auto u : g[v]) { if(u == p) continue; // erase invalid if(s[v] == ')') { int pu = find(u); auto it = path[pu][0].lower_bound({bal[v], -inf}); if(it != path[pu][0].end() && it->first == bal[v]) { path[pu][0].erase(it); } } if(s[v] == '(') { int pu = find(u); auto it = path[pu][1].lower_bound({bal[v], -inf}); if(it != path[pu][1].end() && it->first == bal[v]) { path[pu][1].erase(it); } } } // straight path if(s[v] == ')') { for(auto u : g[v]) { if(u == p) continue; int pu = find(u); auto it = path[pu][0].lower_bound({bal[p], -inf}); if(it != path[pu][0].end() && it->first == bal[p]) { ans += it->second; } } } else { for(auto u : g[v]) { if(u == p) continue; int pu = find(u); auto it = path[pu][1].lower_bound({bal[p], -inf}); if(it != path[pu][1].end() && it->first == bal[p]) { ans += it->second; } } } // calc answer, merging for(auto u : g[v]) { if(u == p) continue; int pu = find(u), pv = find(v); if((path[pu][0].size() + path[pu][1].size()) > (path[pv][0].size() + path[pv][1].size())) { swap(pu, pv); } for(auto [b, c] : path[pu][0]) { int k = b - bal[p]; k = -k + bal[v]; auto it = path[pv][1].lower_bound({k, -inf}); if(it != path[pv][1].end() && it->first == k) { ans += 1LL * c * it->second; } } for(auto [b, c] : path[pu][1]) { int k = b - bal[p]; k = -k + bal[v]; auto it = path[pv][0].lower_bound({k, -inf}); if(it != path[pv][0].end() && it->first == k) { ans += 1LL * c * it->second; } } par[pu] = pv; for(auto x : path[pu][0]) { auto it = path[pv][0].lower_bound({x.first, -inf}); if(it != path[pv][0].end() && it->first == x.first) { path[pv][0].insert({x.first, x.second + it->second}); path[pv][0].erase(it); } else { path[pv][0].insert(x); } } for(auto x : path[pu][1]) { auto it = path[pv][1].lower_bound({x.first, -inf}); if(it != path[pv][1].end() && it->first == x.first) { path[pv][1].insert({x.first, x.second + it->second}); path[pv][1].erase(it); } else { path[pv][1].insert(x); } } path[pu][0].clear(); path[pu][1].clear(); } // add new path if(s[v] == '(') { int pv = find(v); auto it = path[pv][0].lower_bound({bal[v], -inf}); if(it != path[pv][0].end() && it->first == bal[v]) { path[pv][0].insert({it->first, it->second + 1}); path[pv][0].erase(*it); } else { path[pv][0].insert({bal[v], 1}); } } else { int pv = find(v); auto it = path[pv][1].lower_bound({bal[v], -inf}); if(it != path[pv][1].end() && it->first == bal[v]) { path[pv][1].insert({it->first, it->second + 1}); path[pv][1].erase(*it); } else { path[pv][1].insert({bal[v], 1}); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> s; s = '#' + s; for(int i = 0; i < N - 1; i++) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } for(int i = 1; i <= N; i++) par[i] = i; bal[1] = (s[1] == '(' ? 1 : -1); dfs(1, 0); cout << ans << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...