点分治的做法很好想,但是会超时。对于这个题,找一个点dfs,统计异或值的个数就行了。。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 100005; const int maxm = 200005; struct Edge { int v, w; Edge *next; }E[maxm], *H[maxn], *edges; int cnt[maxn << 1]; int a[maxn], n, m; void addedges(int u, int v, int w) { edges->v = v; edges->w = w; edges->next = H[u]; H[u] = edges++; } void init() { edges = E; memset(H, 0, sizeof H); } void dfs(int u, int fa, int dist) { cnt[dist]++; a[u] = dist; for(Edge *e = H[u]; e; e = e->next) if(e->v != fa) dfs(e->v, u, dist ^ e->w); } void work() { scanf("%d", &n); for(int i = 1; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); addedges(a, b, c); addedges(b, a, c); } memset(cnt, 0, sizeof cnt); dfs(1, 1, 0); scanf("%d", &m); while(m--) { LL ans = 0; int s; scanf("%d", &s); for(int i = 1; i <= n; i++) { if(s == 0) ans += cnt[a[i]] + 1; else ans += cnt[a[i] ^ s]; } printf("%lld\n", ans / 2); } } int main() { int _; scanf("%d", &_); while(_--) { init(); work(); } return 0; }