Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ss second
- #define ff first
- #define p_b push_back
- #define endl "\n"
- typedef long long ll;
- typedef long double ld;
- const ll INF = 2e18;
- const ll INFINT = 2e9;
- const int N = 1000006;
- const int NN = 1006;
- ll ans = 0;
- int n;
- int CR = 10;
- int sz[N];
- bool wasCentroid[N];
- int startbal, last[2][N];
- vector < int > g[N];
- string s;
- vector < int > kek[2];
- void Calc_Size (int v, int p = -1) {
- sz[v] = 1;
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- Calc_Size(to, v);
- sz[v] += sz[to];
- }
- }
- int Find_Centroid (int v, int p = -1, int SZ = -1) {
- if (p == -1) SZ = sz[v];
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- if (sz[to] < SZ / 2) continue;
- return Find_Centroid(to, v, SZ);
- }
- return v;
- }
- void dfs_fnd_pre (int v, int p, int bal) {
- //cerr << "FND PRE " << bal << endl;
- if (s[v] == '(') bal++;
- else bal--;
- if (bal >= 0 && bal + startbal >= 0 && s[v] == '(') {
- // cout << "PRE " << v << ' ' << bal << ' ' << kek[1][bal + startbal] << endl;
- if (last[1][bal + startbal] != CR) {
- last[1][bal + startbal] = CR;
- kek[1][bal + startbal] = 0;
- }
- // cout << "PREF " << v + 1 << ' ' << bal << ' ' << kek[1][bal + startbal] << endl;
- ans += kek[1][bal + startbal];
- }
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- dfs_fnd_pre(to, v, bal);
- }
- }
- void dfs_fnd_suff (int v, int p, int bal) {
- //cerr << "FND SUFF " << bal << endl;
- if (s[v] == '(') bal++;
- else bal--;
- if (bal <= 0 && bal + startbal <= 0 && s[v] == ')') {
- if (last[0][-(bal + startbal)] != CR) {
- last[0][-(bal + startbal)] = CR;
- kek[0][-(bal + startbal)] = 0;
- }
- // cout << "SUFF " << v << ' ' << bal << ' ' << kek[0][bal + startbal] << endl;
- // cout << "SUFF " << v + 1 << ' ' << bal << ' ' << kek[0][-(bal + startbal)] << endl;
- ans += kek[0][-(bal + startbal)];
- }
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- dfs_fnd_suff(to, v, bal);
- }
- }
- void dfs_pls_pre (int v, int p, int bal) {
- //cerr << "PLS PRE " << bal << endl;
- if (s[v] == '(') bal++;
- else bal--;
- if (bal + startbal >= 0 && s[v] == '(') {
- if (last[0][bal] != CR) {
- last[0][bal] = CR;
- kek[0][bal] = 0;
- }
- kek[0][bal]++;
- }
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- dfs_pls_pre(to, v, bal);
- }
- }
- void dfs_pls_suff (int v, int p, int bal) {
- //cerr << "PLS SUFF " << bal << endl;
- if (s[v] == '(') bal++;
- else bal--;
- if (bal + startbal <= 0 && s[v] == ')') {
- if (last[1][-bal] != CR) {
- last[1][-bal] = CR;
- kek[1][-bal] = 0;
- }
- kek[1][-bal]++;
- }
- for (int to : g[v]) {
- if (to == p || wasCentroid[to]) continue;
- dfs_pls_suff(to, v, bal);
- }
- }
- void go (int v) {
- Calc_Size(v);
- v = Find_Centroid(v);
- CR++;
- //cout << "CENTR " << 1 + v << endl;
- //cerr << v << endl;//
- //cout << "CENTROID " << v << endl;
- //kek[0].assign (kek[0].size(), 0);
- //kek[1].assign (kek[1].size(), 0);
- kek[0][0] = kek[1][0] = 1;
- last[0][0] = last[1][0] = CR;
- if (s[v] == '(') startbal = 1;
- else startbal = -1;
- for (int to : g[v]) {
- //cerr << to << endl;
- if (wasCentroid[to]) continue;
- dfs_fnd_pre(to, v, 0);
- dfs_fnd_suff(to, v, 0);
- dfs_pls_pre(to, v, 0);
- dfs_pls_suff(to, v, 0);
- //cout << to + 1 << endl;
- // cout << ans << endl;
- //for (int i = 0; i < n; i++) cout << kek[0][i] << ' ' << kek[1][i] << endl;
- // cout << endl;
- }
- //exit(0);
- wasCentroid[v] = 1;
- for (int i = 0; i < g[v].size(); i++) {
- if (wasCentroid[g[v][i]]) continue;
- go(g[v][i]);
- }
- }
- int main () {
- ios_base::sync_with_stdio(0);
- #ifdef LOCAL
- freopen ("input.txt", "r", stdin);
- freopen ("output.txt", "w", stdout);
- #else
- //freopen ("input.txt", "r", stdin);freopen ("output.txt", "w", stdout);
- //freopen ("dynamic.in", "r", stdin);freopen ("dynamic.out", "w", stdout);
- #endif // LOCAL
- cin >> n;
- cin >> s;
- for (int i = 0; i < n - 1; i++) {
- int x, y;
- cin >> x >> y;
- x--, y--;
- g[x].p_b(y);
- g[y].p_b(x);
- }
- kek[0].resize(n + 10);
- kek[1].resize(n + 10);
- go(0);
- cout << ans << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement