제출 #1131181

#제출 시각아이디문제언어결과실행 시간메모리
1131181woohyun_jngZagrade (COI17_zagrade)C++20
10 / 100
2178 ms99668 KiB
#include <bits/stdc++.h> #define MAX 300100 #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; #define ordered_set tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> using namespace std; int N, S[MAX], sz[MAX]; bool chk[MAX]; ordered_set st[MAX * 2]; vector<int> adj[MAX]; int get_size(int node, int par) { int res = 1; for (int i : adj[node]) { if (i == par || chk[i]) continue; res += get_size(i, node); } return sz[node] = res; } int get_centroid(int node, int par, int cap) { for (int i : adj[node]) { if (i == par || chk[i]) continue; if (sz[i] * 2 > cap) return get_centroid(i, node, cap); } return node; } void dfs_first(int node, int par, int sum, int mn) { st[sum + N].insert(mn); for (int i : adj[node]) { if (i == par || chk[i]) continue; dfs_first(i, node, sum + S[i], min(mn, sum + S[i])); } } int dfs(int node, int par, int sum, int mx) { int res = 0; if (sum - mx >= 0) res += st[-sum + N].size() - st[-sum + N].order_of_key(-sum); for (int i : adj[node]) { if (i == par || chk[i]) continue; res += dfs(i, node, sum + S[i], max(mx, sum + S[i])); } return res; } void clear(int node, int par, int sum, int mn) { st[sum + N].erase(st[sum + N].find_by_order(st[sum + N].order_of_key(mn))); for (int i : adj[node]) { if (i == par || chk[i]) continue; clear(i, node, sum + S[i], min(mn, sum + S[i])); } } int divide_and_conquer(int node) { int cent = get_centroid(node, 0, get_size(node, 0)); chk[cent] = true; int res = 0; st[S[cent] + N].insert(S[cent]); for (int i : adj[cent]) { if (chk[i]) continue; dfs_first(i, cent, S[cent] + S[i], min(S[cent], S[cent] + S[i])); } for (int i : adj[cent]) { if (chk[i]) continue; clear(i, cent, S[cent] + S[i], min(S[cent], S[cent] + S[i])); int X = dfs(i, cent, S[i], max(0, S[i])); res += X; dfs_first(i, cent, S[cent] + S[i], min(S[cent], S[cent] + S[i])); } res += st[0 + N].size() - st[0 + N].order_of_key(0); st[S[cent] + N].erase(st[S[cent] + N].find_by_order(st[S[cent] + N].order_of_key(S[cent]))); for (int i : adj[cent]) { if (chk[i]) continue; clear(i, cent, S[cent] + S[i], min(S[cent], S[cent] + S[i])); } for (int i : adj[cent]) { if (chk[i]) continue; res += divide_and_conquer(i); } return res; } signed main() { ios_base::sync_with_stdio(false); cin.tie(0), cout.tie(0); int U, V; string T; cin >> N >> T; for (int i = 1; i <= N; i++) S[i] = T[i - 1] == '(' ? 1 : -1; for (int i = 1; i < N; i++) { cin >> U >> V; adj[U].push_back(V), adj[V].push_back(U); } cout << divide_and_conquer(1) << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...