1 3 1 2 1 2 3 2 3 2 3 4
1 1 0HintFor the first query, (2, 3) is the only pair that f(u, v) = 2. For the second query, (1, 3) is the only one. For the third query, there are no pair (u, v) such that f(u, v) = 4.
求无序的u,v,使得u到v的路径的异或和为s。
从任意一点dfs,记录点到跟的路径上的异或和。
对于每个询问枚举异或值,然后相乘累加。
因为算出的是有序的结果,最后要除以2.
并且对于s = 0时,由于u,u只算了一次,要加起来。
#pragma comment(linker,"/STACK:102400000,102400000") #include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; struct Node{ int v,d; Node (int _v=0,int _d=0):v(_v),d(_d){} }; #define maxn 100007 vector<Node> head[maxn]; int ans[2*maxn]; void dfs(int u,int f,int n){ ans[n]++; for(int i = 0 ;i < head[u].size() ;i++){ if(head[u][i].v != f){ dfs(head[u][i].v,u,n^head[u][i].d); } } } int main(){ int t,n,q,a,b,c,s; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i = 0;i <= n; i++) head[i].clear(); for(int i = 1;i < n; i++){ scanf("%d%d%d",&a,&b,&s); head[a].push_back(Node(b,s)); head[b].push_back(Node(a,s)); } scanf("%d",&q); memset(ans,0,sizeof(ans)); dfs(1,0,0); while(q--){ scanf("%d",&s); long long res = 0; for(int i = 0;i < (1<<17); i++){ if(ans[i] == 0) continue; res += 1LL*ans[i]*ans[i^s]; } if(s == 0) res += n; printf("%I64d\n",res/2); } } return 0; }