点分治的做法很好想,但是会超时。对于这个题,找一个点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;
}