题意:给一棵n个节点的树(无向边),有q个询问,每个询问有一个值s,问有多少点对(u,v)的xor和为s? 注意:(u,v)和(v,u)只算一次。而且u=v也是合法的。

思路:任意点对之间的路径肯定经过LCA的,但是如果如果知道某个点t到根的路径xor和为e,那么就能够得知 x^e=s中的x应该是多少,那就算有多少点到根的xor和为x即可。e是表示t到根的,所以而x也是其他点到根的路径xor和,两个点他们的LCA到根这段会被算2次,那么xor就为0了。

  (1)DFS算出每个点到根的路径xor和,相同的用一个桶装起来,复杂度O(n)。

  (2)对于每个询问s,穷举树上n个点,找到另一个点到root的路径xor和,在对应桶里的都是可以组成s的。(注意要去重)

  特别要注意的是,s可能为0,那么就有x^x=s的情况,另一个点也会在同一个桶里。还有,要用long long保存答案。

 #include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x7f7f7f7f
#define LL long long
using namespace std;
const int N=;
vector<int> vect[N];
struct node
{
int from,to,val;
node(){};
node(int from,int to,int val):from(from),to(to),val(val){};
}edge[N*];
int edge_cnt, n, buck[N*], self[N], vis[N], q; void add_node(int from,int to,int val)
{
edge[edge_cnt]=node(from, to, val);
vect[from].push_back(edge_cnt++);
} void DFS(int x,int sum)
{
vis[x]=;
for(int i=; i<vect[x].size(); i++)
{
node &e=edge[vect[x][i]];
if( !vis[e.to])
{
buck[ self[e.to]=sum^e.val ]++;
DFS(e.to, sum^e.val);
}
}
} LL get_ans(int a)
{
LL ans=;
if(a==)
{
for(int j=; j<=n; j++)
{
int t=self[j]; //a为0,这个桶肯定是自己的那个
ans+=buck[ t ]-; //先扣掉自己。但是仍然会算重了。它到别人,别人也会到他。
}
ans+=n*; //每个点到自己都算。
}
else //a!=0,那么不可能有两个相同数的异或和为a的。
{
for(int j=; j<=n; j++)
{
int t=a^self[j]; //这个肯定不跟j同个桶。
ans+=buck[t];
}
}
return ans/; //去重
} void cal(int n)
{
memset(vis, , sizeof(vis));
memset(buck, , sizeof(buck));
memset(self, , sizeof(self));
DFS(, );
cin>>q;
for(int i=,a=; i<q; i++)
{
scanf("%d", &a);
printf("%lld\n", get_ans(a));
}
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b, c;
cin>>t;
while(t--)
{
cin>>n;
edge_cnt=;
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<n; i++)
{
scanf("%d%d%d", &a, &b, &c);
add_node(a,b,c);
add_node(b,a,c);
}
add_node(, , ); //虚拟的根节点,0号节点
cal(n);
}
return ;
}

AC代码

数据

2

3
1 2 1
2 3 2
3
2
3
4

4
1 2 1
2 3 2
2 4 1
4
0
1
2
3

答案:

1
1
0
5
2
1
2

HDU 5416 CRB and Tree (技巧)的更多相关文章

  1. Hdu 5416 CRB and Tree (bfs)

    题目链接: Hdu 5416 CRB and Tree 题目描述: 给一棵树有n个节点,树上的每条边都有一个权值.f(u,v)代表从u到v路径上所有边权的异或值,问满足f(u,v)==m的(u, v) ...

  2. HDU 5416 CRB and Tree(前缀思想+DFS)

    CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  3. HDU 5416——CRB and Tree——————【DFS搜树】

    CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  4. hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)

    CRB and Tree                                                             Time Limit: 8000/4000 MS (J ...

  5. HDU 5416 CRB and Tree (2015多校第10场)

    欢迎參加--每周六晚的BestCoder(有米!) CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536 ...

  6. HDU 5416 CRB and Tree

    题目大意: T, T组测试数据 给你一个n有n个点,下标是从 1 开始的.这个是一棵树,然后下面是n-1条边, 每条边的信息是 s,e,w 代表 s-e的权值是w 然后是一个Q代表Q次询问. 每次询问 ...

  7. HDOJ 5416 CRB and Tree DFS

    CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  8. HDU 5416 CBR and tree

    #include<bits/stdc++.h> using namespace std; #define for(i,a,b) for(int i=a;i<=b;++i) //T,N ...

  9. 异或+构造 HDOJ 5416 CRB and Tree

    题目传送门 题意:给一棵树,问f (u, v) 意思是u到v的所有路径的边权值的异或和,问f (u, v) == s 的u,v有几对 异或+构造:首先计算f (1, u) 的值,那么f (u, v) ...

随机推荐

  1. mysql负载均衡方案

    mysql负载均衡方案 一.直接连接 数据库的读写分离方案很多,这里介绍基于mysql数据库的读写分离方案. 比较常见的读写分离方案如下: 1 基于查询分离 最简单的分离方法是将读和写分发到主和从服务 ...

  2. innobackupex参数说明

    1.备份: #常用参数 --user:该选项表示备份账号. --password:该选项表示备份的密码. --port:该选项表示备份数据库的端口. --host:该选项表示备份数据库的地址. --s ...

  3. UltraISO制作U盘启动盘-centos7

    1.下载.安装UltraISO软件,(网上找到下载) 2.安装好以后,打开软件,显示如下界面: 3.选择镜像 点击菜单栏的“文件”选项,再点击“打开”按钮,选择要刻录的系统镜像: 4.点击菜单栏的“启 ...

  4. error: expected ‘)’ before ‘PRId64’(转载)

    转自:www.xuebuyuan.com/2077822.html error: expected ‘)’ before ‘PRId64’ 原来这个宏定义给c用的,C++要用它,就要定义一个__STD ...

  5. CSA Round #50 (Div. 2 only) Min Swaps(模拟)

    传送门 题意 给出一个排列,定义\(value为\sum_{i=1}^{n-1}abs(f[i+1]-f[i])\) \(swap(a[i],a[j])(i≠j)为一次交换\),询问最少的交换次数使得 ...

  6. 51单片机 HC05蓝牙模块

    一.注意事项 1.烧写程序时,要把蓝牙tx,rx信号线拔掉,对烧写程序有影响. 2.执行HC05集命令时,均以\r\n结尾.串口中断若选择“发送新行”时,不用添加\r\n.原理相同. 二.准备软硬件 ...

  7. Luogu P4889 kls与flag 【思维/排序】By cellur925

    题目传送门 这题真的一点也不难qwq.只要想出来就没有什么代码难度的qwq. 每个竹竿只可能向左倒或向右倒,把这两种情况都存在数组中,将数组排序,就可以知道最后落在同一位置的有多少竹竿.就可以知道落在 ...

  8. Mac 解登录密码Keychain

    在终端输入: security unlock-keychain -p "login pwd" ~/Library/Keychains/login.keychain 在制作macOS ...

  9. Oracle之Char VarChar VarChar2

    Oracle之Char VarChar VarChar2 在Oracle数据库中,字符类型有Char.VarChar和VarChar2三种类型,但不大清楚各自区别在哪儿,平时基本上就是用VarChar ...

  10. Codeforces Round #261 (Div. 2) C

    Description Recently Pashmak has been employed in a transportation company. The company has kbuses a ...