Submission #869743

#TimeUsernameProblemLanguageResultExecution timeMemory
869743NeroZeinZagrade (COI17_zagrade)C++17
100 / 100
539 ms48580 KiB
#include "bits/stdc++.h"
using namespace std;

#ifdef Nero
#include "Deb.h"
#else
#define deb(...)
#endif  

const int N = 3e5 + 5;

int a[N]; 
int sz[N]; 
int cnt[N]; 
bool blocked[N]; 
vector<int> g[N]; 

void find_sizes(int v, int p) {
  sz[v] = 1;
  for (int u : g[v]) {
    if (!blocked[u] && u != p) {
      find_sizes(u, v); 
      sz[v] += sz[u];
    }
  }
}

int find_centroid(int v, int p, int x) {
  for (int u : g[v]) {
    if (!blocked[u] && u != p && sz[u] > x / 2) {
      return find_centroid(u, v, x); 
    }
  }
  return v;
}

void dfs(long long& ret, int v, int p, int sum, int mx, int upd, int rev) {
  sum += a[v] * rev;
  mx = max(mx, sum); 
  if (sum == mx) {
    if (!upd) {
      ret += cnt[sum];
    } else {
      cnt[sum] += upd; 
    }
  }
  for (int u : g[v]) {
    if (!blocked[u] && u != p) {
      dfs(ret, u, v, sum, mx, upd, rev); 
    }
  }
}

long long solve(int root) {
  find_sizes(root, root); 
  int centroid = find_centroid(root, root, sz[root]); 
  blocked[centroid] = true;
  long long ret = 0;
  if (a[centroid] == 1) cnt[1] = 1; 
  for (int u : g[centroid]) {
    if (!blocked[u]) {
      dfs(ret, u, centroid, 0, 0, 0, -1);
      dfs(ret, u, centroid, a[centroid], max(0, a[centroid]), 1, 1);
    }
  }
  fill(cnt, cnt + sz[root] + 1, 0);
  if (a[centroid] == -1) cnt[1] = 1; 
  for (int u : g[centroid]) {
    if (!blocked[u]) {
      dfs(ret, u, centroid, 0, 0, 0, 1);
      dfs(ret, u, centroid, -a[centroid], max(0, -a[centroid]), 1, -1);
    }
  }
  fill(cnt, cnt + sz[root] + 1, 0);
  for (int u : g[centroid]) {
    if (!blocked[u]) {
      ret += solve(u); 
    }
  }
  return ret; 
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    char c;
    cin >> c;
    a[i] = (c == '(' ? 1 : -1); 
  }
  for(int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  cout << solve(1) << '\n'; 
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...