您的位置:首页 > 其它

hdu 5416 CRB and Tree 2015多校联合训练赛#10 枚举

2015-08-21 15:37 513 查看


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?



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.



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

2015 Multi-University Training Contest 10

求无序的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
++;
    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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: