给一个s,问一棵树上两点间的路径的亦或值等于s的有几种情况,主要有一个公式 f(1,u)^f(1,v)=f(u,v),另外特判下s==0的情况
#include<stdio.h> #include<string> #include<map> #include<vector> #include<cmath> #include<stdlib.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; #define rep(i,n) for(int i=0;i<n;i++) const int N=1e5+10; const int MOD=1e9+7; int n,m,k,up; int dep[N]; int head[N]; int q[N]; int cnt[1<<19]; struct Edge{ int to,w,nxt; }edge[N*2]; int tot; void addEdge(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot++; } void init(){ tot=0; memset(head,-1,sizeof head); } void calc(){ memset(dep,-1,sizeof dep); int f=1,r=0; q[++r]=1; dep[r]=0; while(f<=r){ int u=q[f++]; for(int i=head[u];~i;i=edge[i].nxt){ int v=edge[i].to,w=edge[i].w; if(dep[v]!=-1) continue; dep[v]=w^dep[u]; q[++r]=v; } } memset(cnt,0,sizeof cnt); for(int i=1;i<=n;i++) cnt[dep[i]]++; } int main(){ #ifndef ONLINE_JUDGE freopen("aaa","r",stdin); //freopen("bbb","w",stdout); #endif int tc; for(scanf("%d",&tc);tc--;){ scanf("%d",&n); init(); for(int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addEdge(u,v,w); addEdge(v,u,w); } calc(); int q,s; for(scanf("%d",&q);q--;){ long long ans=0; scanf("%d",&s); for(int i=1;i<=n;i++) ans+=cnt[dep[i]^s]; if(!s) ans+=n; ans/=2; printf("%I64d\n",ans); } } }