CRB and Tree
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 628 Accepted Submission(s): 198
Problem Description
CRB has a tree, whose vertices are labeled by 1, 2, …,
N
. They are connected by
N
– 1 edges. Each edge has a weight.
For any two vertices u and v (possibly equal), f(u,v) is xor(exclusive-or) sum of weights of all edges on the path from u to v .
CRB’s task is for given s , to calculate the number of unordered pairs (u,v) such that f(u,v) = s . Can you help him?
For any two vertices u and v (possibly equal), f(u,v) is xor(exclusive-or) sum of weights of all edges on the path from u to v .
CRB’s task is for given s , to calculate the number of unordered pairs (u,v) such that f(u,v) = s . Can you help him?
Input
There are multiple test cases. The first line of input contains an integer
T
, indicating the number of test cases. For each test case:
The first line contains an integer N denoting the number of vertices.
Each of the next N - 1 lines contains three space separated integers a , b and c denoting an edge between a and b , whose weight is c .
The next line contains an integer Q denoting the number of queries.
Each of the next Q lines contains a single integer s .
1 ≤ T ≤ 25
1 ≤ N ≤ 105
1 ≤ Q ≤ 10
1 ≤ a , b ≤ N
0 ≤ c , s ≤ 105
It is guaranteed that given edges form a tree.
The first line contains an integer N denoting the number of vertices.
Each of the next N - 1 lines contains three space separated integers a , b and c denoting an edge between a and b , whose weight is c .
The next line contains an integer Q denoting the number of queries.
Each of the next Q lines contains a single integer s .
1 ≤ T ≤ 25
1 ≤ N ≤ 105
1 ≤ Q ≤ 10
1 ≤ a , b ≤ N
0 ≤ c , s ≤ 105
It is guaranteed that given edges form a tree.
Output
For each query, output one line containing the answer.
Sample Input
1 3 1 2 1 2 3 2 3 2 3 4
Sample Output
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.
Author
KUT(DPRK)
Source
求无序的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;
}