Untitled

small to large with keeping at each node map corresponding to its subtree
mail@pastecode.io avatar
unknown
c_cpp
17 days ago
3.5 kB
2
Indexable
Never
#include <bits/stdc++.h>
using namespace std ; 
#ifndef ONLINE_JUDGE
#include "debugger.cpp"
#else
#define debug(...)
#define debugArr(...)
#define show(...)
#endif
template<typename... T>void read(T&... args) {((cin >> args), ...);}
template<typename... T>void print(T&&... args) {((cout << args ), ...);}
template <class T> using V = vector<T>;
#define pb push_back
#define int long long  
typedef long long ll ; typedef array<int, 2> pi ; typedef vector<int> vi ; 
#define len(v) (int)v.size()
#define FOR( i , debut,  fin) for( ll i = debut ; i<fin ; i++   )
#define all(x) x.begin(), x.end() 
#define getunique(vt)  vt.erase(unique(all(vt)), vt.end()) 
void YES(bool x) { if (x) cout << ("Yes\n"); else cout << ("No\n"); }

void input_output();
const int N = 4e5; 
int n ; 
vector<pi>adj[N];
int depth[N] , parent[N] , pfxor[N]; 
map<int,int>mp[N] ;
void calsz ( int nd , int pr , int xpf   ){
    depth[nd] = 1 ;
    pfxor[nd] = xpf ; 
    for ( auto &[ch,_]:  adj[nd]){
        if ( ch == pr ) continue;
        calsz(ch , nd  , xpf ^ _   );
        parent[ch] = nd ;   
        depth[nd] += depth[ch]; 
    }
}
int ans = 0 ;
void addto( int nd , int pr , int where) {
    for ( int bt = 0 ; bt < 28 ; bt++ ){
        int x = 1LL << bt ; 
        int need2 = pfxor[nd]^ x ;
        if ( !mp[where].count(need2)) continue;
        ans += mp[where][need2] ; 
    }
    ans += mp[where][pfxor[nd]];
    for ( auto &[ch, _ ]: adj[nd]){
        if ( ch == pr )continue;
        addto(ch,nd,where);
    }
}
void addtomap ( int nd , int pr , int where) {
    mp[where][pfxor[nd]]++ ;
    for ( auto &[ch, _ ]: adj[nd]){
        if ( ch == pr )continue;
        addtomap(ch,nd,where);
    }
}
void dfs ( int nd , int pr ){
    int MX = -1 , BIG = -1 ; 
    for ( auto &[ch,w]: adj[nd]){
        if ( ch == pr ) continue;
        if( MX < depth[ch]) BIG = ch , MX = depth[ch]; 
    }
    for ( auto &[ch,w]:adj[nd]){
        if ( ch == pr or ch == BIG )continue; 
        dfs(ch,nd);
    }
    if( BIG != -1)  dfs(BIG,nd);
    int prfparent =pfxor[nd] ;
    int needed1 = prfparent ;
    if ( BIG != -1 ){
        swap(mp[nd],  mp[BIG]);
    } 
    ans += mp[nd][needed1]  ; 
    for ( int bt = 0 ; bt < 28 ; bt++ ){
        int x = 1LL << bt ; 
        int need2 = prfparent ^ x ; 
        if ( !mp[nd].count(need2)) continue;
        ans += mp[nd][need2] ;
    }
    mp[nd][needed1]++ ; 
    for ( auto &[ch,_] :adj[nd]){
        if ( ch == pr or ch == BIG ) continue;
        addto(ch,nd , nd );
        addtomap(ch,nd,nd) ; 
    }
}
void solve(){
    read (n);
    ans = 0 ; 
    FOR (i , 0 , n-1 ){
        int u , v ; 
        char a ; 
        read ( u , v , a  );
        int msk = 1LL << (a- 'a') ;
        adj[u].push_back({v,msk});
        adj[v].push_back({u,msk});
    }
    pfxor[0] = 0 ;
    calsz(1 , 0 , 0 );
    dfs(1,0);
    print(ans);
}
    

int32_t main() {
    input_output();
    int t = 1;
    for ( int i = 1 ; i <= t ; i++ ){
        show("------- Case " , i, "------- : " );
        solve();
        show("---------------------- .\n \n ");      
    }     
    double Time_elapsed= 1.0 * clock() / CLOCKS_PER_SEC ; 
    debug(Time_elapsed);
        
}


void input_output() {
    cout.tie(0), cin.tie(0), ios_base::sync_with_stdio(0) ;  
    cout << fixed << setprecision(14) ; 
    cerr << fixed << setprecision(14) ; 
    #ifndef ONLINE_JUDGE 
    freopen("inp.txt", "r", stdin); freopen("out.txt", "w", stdout); freopen("err.txt", "w", stderr); 
    #endif
}
Leave a Comment