hdu 5416 树上的异或(思路题)

题意:给定一棵树,树上任意两点的距离为其路径上的边权的异或值,求距离等于某个值的点的对数。

思路:这道题关键是要利用异或的性质。异或最基本的一个性质是和同一个数异或两次不发生改变。而对于这道题来说求出任意两点间的距离是不现实的,但是利用异或的性质,如果我们有了每个点到根的距离,就能间接得到任意两点间的距离,对于任意两点u和v,他们之间的距离就是他们到根的距离异或起来。因为不在u到v路径上的那些边权(即lca(u,v)到根的路径上的边)被异或了两次等于没算,想到这一点就好做了,我们只要借助hash来统计答案即可,注意为查询为0的情况。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6
 7 typedef long long ll;
 8 const int N = 200001;
 9 int mp[N];
10 int head[N];
11 int n, e;
12
13 void init()
14 {
15     e = 0;
16     memset( head, -1, sizeof(head) );
17     memset( mp, 0, sizeof(mp) );
18 }
19
20 struct Edge
21 {
22     int v, next, w;
23 } edge[N];
24
25 void addEdge( int u, int v, int w )
26 {
27     edge[e].v = v;
28     edge[e].w = w;
29     edge[e].next = head[u];
30     head[u] = e++;
31 }
32
33 void dfs( int u, int fa, int val )
34 {
35     mp[val]++;
36     for ( int i = head[u]; i != -1; i = edge[i].next )
37     {
38         int v = edge[i].v, w = edge[i].w;
39         if ( v == fa ) continue;
40         dfs( v, u, val ^ w );
41     }
42 }
43
44 int main ()
45 {
46     int t;
47     scanf("%d", &t);
48     while ( t-- )
49     {
50         scanf("%d", &n);
51         init();
52         for ( int i = 1; i < n; i++ )
53         {
54             int u, v, w;
55             scanf("%d%d%d", &u, &v, &w);
56             addEdge( u, v, w );
57             addEdge( v, u, w );
58         }
59         dfs( 1, -1, 0 );
60         int q;
61         scanf("%d", &q);
62         while ( q-- )
63         {
64             int tt;
65             scanf("%d", &tt);
66             ll ans = 0;
67             if ( tt == 0 )
68             {
69                 for ( int i = 0; i < N; i++ )
70                 {
71                     ans += ( ll ) mp[i] * ( mp[i] + 1 ) / 2;
72                 }
73             }
74             else
75             {
76                 for ( int i = 0; i < N; i++ )
77                 {
78                     int tmp = tt ^ i;
79                     if ( tmp >= N ) continue;
80                     ans += ( ll ) mp[i] * mp[tmp];
81                 }
82                 ans = ans >> 1;
83             }
84             printf("%I64d\n", ans);
85         }
86     }
87     return 0;
88 }
时间: 2024-12-11 08:46:42

hdu 5416 树上的异或(思路题)的相关文章

Hdu 5416 CRB and Tree (bfs)

题目链接: Hdu 5416 CRB and Tree 题目描述: 给一棵树有n个节点,树上的每条边都有一个权值.f(u,v)代表从u到v路径上所有边权的异或值,问满足f(u,v)==m的(u, v)有多少中情况(u, v有可能相同)? 解题思路: 由于xor的特殊性质.x^x=0,对于求f(u, v) == f(u, 1) ^ f(1, u). 又因为x^y == z可以推出x^z == y,对于f(u, 1) ^ f(1, v) == m可以转化为m ^ f(1, v) == f(u, 1)

hdu 4828 Xor Sum (trie 树模板题,经典应用)

hdu 4825 题目链接 题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大. 思路:字典树..把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数. 如果想要异或和最大,那么每一位尽可能都是1. 所以做法是,先构建字典树,然后每次find的时候,尽可能按照和当前寻找的数的位相反的位的方向走(如果有的话) 比如当前位是1,那我就往0的方向走. 需要注意的是,多组数据,每次要重新初始化一遍. 做法是 在struct 中重新 root = new N

HDU 4007 Dave (基本算法-水题)

Dave Problem Description Recently, Dave is boring, so he often walks around. He finds that some places are too crowded, for example, the ground. He couldn't help to think of the disasters happening recently. Crowded place is not safe. He knows there

hdu 1201 18岁生日 (简单题)

18岁生日 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18281    Accepted Submission(s): 5776 Problem Description Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他

2014 HDU多校弟九场I题 不会DP也能水出来的简单DP题

听了ZWK大大的思路,就立马1A了 思路是这样的: 算最小GPA的时候,首先每个科目分配到69分(不足的话直接输出GPA 2),然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到100即可 算最大GPA的时候,首先每个科目分配到60分,然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到85即可,如果还有REMAIN POINT,就FOR循环下来加到100上限即可 不会DP 阿 QAQ 过段时间得好好看DP了  =  = 于是默默的把这题标记为<水题集> //

hdu 1202The calculation of GPA (简单题+坑)

The calculation of GPA Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18748    Accepted Submission(s): 4331 Problem Description 每学期的期末,大家都会忙于计算自己的平均成绩,这个成绩对于评奖学金是直接有关的.国外大学都是计算GPA(grade point a

HDU 4022 Bombing(基本算法-水题)

Bombing Problem Description It's a cruel war which killed millions of people and ruined series of cities. In order to stop it, let's bomb the opponent's base. It seems not to be a hard work in circumstances of street battles, however, you'll be encou

hdu 4274 Spy&#39;s Work(水题)

Spy's Work Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1266    Accepted Submission(s): 388 Problem Description I'm a manager of a large trading company, called ACM, and responsible for the

HDU 1862 EXCEL排序 (排序水题)

Problem Description Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. Input 测试输入包含若干测试用例.每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号.以下有 N 行,每行包含一条学生纪录.每条学生纪录由学号(6位数字,同组测试中没有重复的学号).姓名(不超过8位且不包含空格的字符串).成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开.当读到 N=0 时,全部输入结