题意:给一颗树,定义f(u,v)为u到v路径上的异或结果,现在给定s,要求异或结果为s的路径有多少条。(1,2)和(2,1)只算一种。

根据异或的特性有f(u,v)=f(1,u)f(1,v),先把f(1,i)的所有i都求出,然后对于每一个u(1~n)如果有f(u,v)=s的话那么有f(1,v)=sf(1,u),所以求一下f(1,v)有多少个,加起来就行了,最后要特殊讨论下s==0的情况。

//author: CHC
//First Edit Time: 2015-08-22 15:41
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
using namespace std;
typedef long long LL;
const int MAXN=100000*2+1000;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
struct Edge {
int to,next,w;
Edge(){}
Edge(int _to,int _next,int _w):to(_to),next(_next),w(_w){}
}e[MAXN<<1];
int head[MAXN],tot;
void init(){
memset(head,-1,sizeof(head));
tot=0;
}
void AddEdge(int u,int v,int w){
e[tot]=Edge(v,head[u],w);
head[u]=tot++;
e[tot]=Edge(u,head[v],w);
head[v]=tot++;
}
int dis[MAXN];
int has[1<<17],N,Q,T;
void dfs(int u,int fa){
++has[dis[u]];
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
if(dis[v]!=-1)continue;
dis[v]=dis[u]^e[i].w;
dfs(v,u);
}
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&N);
init();
for(int i=0,x,y,w;i<N-1;i++){
scanf("%d%d%d",&x,&y,&w);
AddEdge(x,y,w);
}
memset(has,0,sizeof(has));
memset(dis,-1,sizeof(dis));
dis[1]=0;
dfs(1,-1);
scanf("%d",&Q);
LL ans=0;
int s;
while(Q--){
scanf("%d",&s);
ans=0;
for(int i=1;i<=N;i++)ans+=has[s^dis[i]];
if(!s)ans+=N;
ans/=2;
printf("%I64d\n",ans);
}
}
return 0;
}