Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem A
Balanced Paths

You are given an undirected tree with $n$ nodes. The nodes are numbered 1 through $n$. Each node is labeled with either '(' or ')'. Let $l[u \rightarrow v]$ denote the string obtained by concatenating the labels of the nodes on the simple path from $u$ to $v$. (Note that the simple path between two nodes is uniquely determined on a tree.) A balanced string is defined as follows:

The empty string is balanced.

For any balanced string $s$, the string "(" $s$ ")" is balanced.

For any balanced strings $s$ and $t$, the string $st$ (the concatenation of $s$ and $t$) is balanced.

Any other string is NOT balanced.

Calculate the number of the ordered pairs of the nodes ($u$, $v$) such that $l[u \rightarrow v]$ is balanced.

Input

The input consists of a single test case. The input starts with an integer $n (2 \leq n \leq 10^5)$, which is the number of nodes of the tree. The next line contains a string of length $n$, each character of which is either '(' or ')'. The $x$-th character of the string represents the label of the node $x$ of the tree. Each of the following $n - 1$ lines contains two integers $a_i$ and $b_i$ $(1 \leq a_i, b_i \leq n)$, which represents that the node $a_i$ and the node $b_i$ are connected by an edge. The given graph is guaranteed to be a tree.

Output

Display a line containing the number of the ordered pairs ($u$, $v$) such that $l[u \rightarrow v]$ is balanced.

Sample Input 1

2
()
1 2

Output for the Sample Input 1

1

Sample Input 2

4
(())
1 2
2 3
3 4

Output for the Sample Input 2

2

Sample Input 3

5
()())
1 2
2 3
2 4
1 5

Output for the Sample Input 3

4

Solution in C++14 (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
using Int = long long;
using ll = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;};

template<typename F>
struct FixPoint : F{
  FixPoint(F&& f):F(forward<F>(f)){}
  template<typename... Args>
  decltype(auto) operator()(Args&&... args) const{
    return F::operator()(*this, forward<Args>(args)...);
  }
};

template<typename F>
inline decltype(auto) MFP(F&& f){
  return FixPoint<F>{forward<F>(f)};
}
  
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  Int n;
  cin>>n;

  string s;
  cin>>s;

  vector< vector<Int> > G(n);
  for(Int i=1;i<n;i++){
    Int x,y;
    cin>>x>>y;
    x--;y--;
    G[x].emplace_back(y);
    G[y].emplace_back(x);
  }

  ll ans=0;
  vector< deque<Int> > dp1(n),dp2(n);
  MFP([&](auto dfs,Int v,Int p)->void{
      Int idx=v;
      for(Int u:G[v]){
        if(u==p) continue;
        dfs(u,v);
        if(dp1[idx].size()+dp2[idx].size()<
           dp1[u].size()+dp2[u].size()) idx=u;
      }
      auto &dx=dp1[v];
      auto &dy=dp2[v];
      
      if(idx!=v){
        for(Int u:G[v]){
          if(u==p) continue;   
          if(u==idx) continue;
          auto &py=dp2[u];
          Int sy=py.size();        
          if(s[v]=='('){
            for(Int i=0;i+1<sy;i++){
              if(i<(Int)dp1[idx].size())
                ans+=(ll)dp1[idx][i]*py[i+1];
            }                    
          }else{
            for(Int i=0;i<sy;i++){
              if(i+1<(Int)dp1[idx].size())
                ans+=(ll)dp1[idx][i+1]*py[i];
            }                    
          }
        }
        swap(dx,dp1[idx]);
        swap(dy,dp2[idx]);
      }else{
        dx.assign(1,0);
        dy.assign(1,0);
      }
      
      for(Int u:G[v]){
        if(u==p) continue;
        if(u==idx) continue;
        auto &px=dp1[u];
        auto &py=dp2[u];
        Int sx=px.size();
        Int sy=py.size();
        
        if((Int)dx.size()<sx) dx.resize(sx,0);
        if((Int)dy.size()<sy) dy.resize(sy,0);
        
        for(Int j=0;j<sx;j++) dx[j]+=px[j];
        for(Int j=0;j<sy;j++) dy[j]+=py[j];        
      }

      // top
      if(s[v]=='('){
        if(1<dy.size()) ans+=dy[1];
      }else{
        if(1<dx.size()) ans+=dx[1]; 
      }

      const Int DEBUG = 0;
      if(DEBUG){
        cout<<ans<<endl;
        for(Int x:dx) cout<<" "<<x;
        cout<<endl;
        for(Int y:dy) cout<<" "<<y;
        cout<<endl;
        cout<<endl;
      }
      
      //lca
      for(Int u:G[v]){
        if(u==p) continue;   
        if(u==idx) continue;
        auto &px=dp1[u];
        auto &py=dp2[u];
        Int sx=px.size();
        Int sy=py.size();        
        if(s[v]=='('){          
          for(Int i=0;i<sx;i++){
            if(i+1<(Int)dy.size())
              ans+=(ll)px[i]*dy[i+1];
            if(i+1<sy)
              ans-=(ll)px[i]*py[i+1];
          }                  
        }else{      
          for(Int i=0;i+1<sx;i++){
            if(i<(Int)dy.size())
              ans+=(ll)px[i+1]*dy[i];
            if(i<sy)
              ans-=(ll)px[i+1]*py[i];
          }                 
        }        
        if(DEBUG){
          cout<<u<<" "<<sx<<" "<<sy<<":"<<ans<<endl;
          for(Int x:px) cout<<" "<<x;
          cout<<endl;
          for(Int y:py) cout<<" "<<y;
          cout<<endl;
          cout<<endl;
        }
      }
      
      for(Int u:G[v]){
        if(u==p) continue;
        dp1[u].clear();
        dp2[u].clear();
      }

      if(dx.empty()) dx.assign(1,0);
      if(dy.empty()) dy.assign(1,0);
      dx[0]+=1;
      dy[0]+=1;
      
      if(s[v]=='('){
        dx.emplace_front(0);
        dy.pop_front();
      }else{
        dx.pop_front();
        dy.emplace_front(0);          
      }
    })(0,-1);
  
  cout<<ans<<endl;
  return 0;
}