题解

dis[u]dis[u]表示从 uu 节点到 11 节点路径异或值

那么如果我们找的那条路径在同一颗子树中(现在的树根为 rtrt)

dis[u]dp[rt]=0dis[u]=dis[rt]dis[u] \oplus dp[rt] = 0 \longrightarrow dis[u] = dis[rt]

如果我们找的那条路径在不同的子树中

(dis[v]dis[rt])(dis[u]dis[rt])=0dis[u]=dis[v](dis[v] \oplus dis[rt]) \oplus (dis[u] \oplus dis[rt]) = 0 \longrightarrow dis[u] = dis[v]

fu,sf_{u,s}: 表示以 uu 为根的子树中, 到 11 节点的路径异或值为 ss 的路径数量。

std:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MAXN = 1e5 + 10;

struct edge {int to; char ch;};

int n;
vector<edge> g[MAXN];
int dis[MAXN];

ll dp[MAXN][64];

// 1.路径在一颗子树中 dis[v] ^ dis[rt] == 0 --> dis[v] == dis[rt]
// 2.路径在不同子树中 (dis[v] ^ dis[rt]) ^ (dis[u] ^ dis[rt]) == 0 --> dis[v] == dis[u]  

ll ans;

void dfs(int u, int fa) {
    for(auto e : g[u]) {
        int v = e.to;
        if(v == fa) continue;
        dis[v] = dis[u] ^ (1 << (e.ch - 'a'));
        dfs(v, u);
        for(int s = 0; s < (1 << 6); s++) {
            ans += dp[v][s] * dp[u][s];
            dp[u][s] += dp[v][s];
        }
        ans += dp[v][dis[u]];
    }
    dp[u][dis[u]]++;
}

void solve() {
    cin >> n;
    for(int i = 1; i < n; i++) {
        int u, v; char ch; cin >> u >> v >> ch;
        g[u].push_back(edge{v, ch});
        g[v].push_back(edge{u, ch});
    }
    dfs(1, 0);
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    solve();
    return 0;
}