Submission #960436

#TimeUsernameProblemLanguageResultExecution timeMemory
960436BlagojZagrade (COI17_zagrade)C++17
100 / 100
650 ms46272 KiB
#include <bits/stdc++.h> using namespace std; #define endl '\n' #define ll long long #define all(x) (x).begin(), (x).end() const int mxn = 3e5 + 10; int n; string s; int sz[mxn]; vector<int> g[mxn]; bool processed[mxn]; int getSize(int cur = 1, int par = -1) { sz[cur] = 1; for (auto x : g[cur]) { if (x != par && !processed[x]) sz[cur] += getSize(x, cur); } return sz[cur]; } int getCentroid(int cur, int des, int par = -1) { for (auto x : g[cur]) { if (x != par && !processed[x] && sz[x] >= des) return getCentroid(x, des, cur); } return cur; } ll ans = 0, cntL[mxn], cntR[mxn]; int mx = 0; // L - side void get1(int cur, int open, int close, int par = -1) { // cout << "?1 " << cur << " " << open << " " << close << " " << par << endl; if (close == 0) ans += cntR[open]; for (auto x : g[cur]) { if (x != par && !processed[x]) { if (s[x] == '(') { if (close) get1(x, open, close - 1, cur); else get1(x, open + 1, close, cur); } if (s[x] == ')') get1(x, open, close + 1, cur); } } } // R - side void get2(int cur, int open, int close, int par = -1) { // cout << "?2 " << cur << " " << open << " " << close << " " << par << endl; if (open == 0) ans += cntL[close]; for (auto x : g[cur]) { if (x != par && !processed[x]) { if (s[x] == ')') { if (open) get2(x, open - 1, close, cur); else get2(x, open, close + 1, cur); } if (s[x] == '(') get2(x, open + 1, close, cur); } } } // L - side void update1(int cur, int open, int close, int par = -1) { // cout << "!1 " << cur << " " << open << " " << close << " " << par << endl; if (close == 0) { cntL[open]++; mx = max(mx, open); } for (auto x : g[cur]) { if (x != par && !processed[x]) { if (s[x] == '(') { if (close) update1(x, open, close - 1, cur); else update1(x, open + 1, close, cur); } if (s[x] == ')') update1(x, open, close + 1, cur); } } } // R - side void update2(int cur, int open, int close, int par = -1) { // cout << "!2 " << cur << " " << open << " " << close << " " << par << endl; if (open == 0) { cntR[close]++; mx = max(mx, close); } for (auto x : g[cur]) { if (x != par && !processed[x]) { if (s[x] == '(') update2(x, open + 1, close, cur); if (s[x] == ')') { if (open) update2(x, open - 1, close, cur); else update2(x, open, close + 1, cur); } } } } void decompose(int cur = 1, int par = -1) { int centroid = getCentroid(cur, getSize(cur) / 2); processed[centroid] = 1; cntL[0] = cntR[0] = 1; int open = s[centroid] == '(', close = s[centroid] == ')'; for (auto x : g[centroid]) { if (x != par && !processed[x]) { if (s[x] == '(') { if (close) get1(x, open, close - 1, centroid); else get1(x, open + 1, close, centroid); get2(x, open + 1, close, centroid); } if (s[x] == ')') { get1(x, open, close + 1, centroid); if (open) get2(x, open - 1, close, centroid); else get2(x, open, close + 1, centroid); } if (s[x] == '(') { update1(x, 1, 0, centroid); update2(x, 1, 0, centroid); } if (s[x] == ')') { update1(x, 0, 1, centroid); update2(x, 0, 1, centroid); } } } // cout << centroid << " " << ans << endl; for (auto x : g[centroid]) { if (x != par && !processed[x]) { for (int i = 0; i <= mx; i++) cntL[i] = cntR[i] = 0; mx = 0; decompose(x, centroid); } } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n; cin >> s; s = "." + s; for (int i = 0; i < n - 1; i++) { int f, t; cin >> f >> t; g[f].push_back(t); g[t].push_back(f); } decompose(); cout << ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...