HDU 5416
CRB and Tree
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
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
0
Hint
For 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
题意:给你一棵树,路径上有权值,q个询问每次给你一个A,要你找出所有路径权值异或和为A的方案数
题解:定义一个根节点1,dfs出所有节点与根节点的异或和, 根据异或:a^b=c,那么b^c=a
代码
///1085422276 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<bitset> #include<set> #include<vector> using namespace std ; typedef long long ll; #define push_back pb #define mem(a) memset(a,0,sizeof(a)) #define TS printf("111111\n"); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a) scanf("%d",&a) #define mod 1000000007 #define inf 100000 #define maxn 300000 inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } //****************************************************************** struct ss { int to,next,v; }e[500001]; int vis[200005],head[200005],t,n; ll hashs[500005]; void add(int u,int v,int w) { ss kk={v,head[u],w}; e[t]=kk; head[u]=t++; } void dfs(int x,int pre) { hashs[pre]++; vis[x]=1; for(int i=head[x];i;i=e[i].next) {//TS; if(vis[e[i].to])continue; dfs(e[i].to,pre^e[i].v); } } int main() { int a,b,c; int T=read(); while(T--) { t=1;mem(head);mem(hashs);mem(vis); n=read(); FOR(i,1,n-1) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } //cout<<t<<endl; dfs(1,0); /// FOR(i,0,3)cout<<hashs[i]<<" "; int q=read(); FOR(i,1,q) { ll ans=0; a=read(); for(int j=0;j<=maxn;j++) {if(!hashs[j])continue; if((a^j)==j)ans+=(hashs[j]*(hashs[j]-1)); else { ans+=(hashs[j]*hashs[a^j]); } //if(ans!=0)cout<<j<<" "<<ans<<endl; }ans=ans/2; if(a==0)ans+=n; cout<<ans<<endl; } } return 0; }
特别考虑A==0的情况,最后方案数/2