比较水,坑点是答案要爆int。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define maxn 511111
#define maxm 1111111
#define INF 111111111
struct node {
int from, to, next, w;
}edge[maxm];
int head[maxn], sum[maxn]; //异或和
int cnt[maxn];
int e, n;
void add_edge (int from, int to, int w, int i) {
node &e = edge[i];
e.from = from, e.to = to, e.w = w, e.next = head[from], head[from] = i;
}
void dfs (int u, int fa) {
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if (v == fa)
continue;
sum[v] = sum[u]^edge[i].w;
dfs (v, u);
}
}
int main () {
int t;
scanf ("%d", &t);
while (t--) {
scanf ("%d", &n);
memset (cnt, 0, sizeof cnt);
memset (head, -1, sizeof head);
e = 0;
int u, v, w;
for (int i = 1; i < n; i++) {
scanf ("%d%d%d", &u, &v, &w);
add_edge (u, v, w, e++);
add_edge (v, u, w, e++);
}
memset (sum, 0, sizeof sum);
dfs (1, 0);
for (int i = 1; i <= n; i++) {
cnt[sum[i]]++;
}
//for (int i = 1; i <= n; i++) cout << sum[i] << " "; cout <<endl;
int q;
scanf ("%d", &q);
while (q--) {
scanf ("%d", &w);
long long ans = 0;
for (int i = 1; i <= n; i++) {
int gg = w^sum[i];
if (sum[i] == gg)
ans++;
ans += cnt[gg];
}
printf ("%lld\n", ans/2);
}
}
return 0;
}