题目链接:https://nanti.jisuanke.com/t/39277

题意:给出一棵有边权的树,求所有简单路径包含异或和为0的简单路径的总数和。

思路:

  首先,对于异或为0这一限制,我们通过dfs得到根节点到所有点的路径上的异或和val[i],如果两个结点的val值相等,说明他们之间的路径满足异或和为0。sz [i]为以i为根的子树 的大小。

  其次,对于满足异或和为0的两个点u、v,分两种情况考虑:

    1. u、v在不同链上,这一条路径的贡献值为sz[u]*sz[v],通过map记录每一种权值的size和即可得到。我们先将所有点这样处理一遍。

    2. u、v在一条链上,这一条路径的贡献值为(n-sz[u1])*sz[v],u1是u与v这一条链上u的第一个子结点。因为上一步我们把所有情况加上了,所以要先减去sz[u]*sz[v],通过mp1来记录同一条链上异或值为val的size和,因为是记录同一条链,所以当处理完一个结点的所有子结点时要回溯更新,即减去前面加的size。减了之后加上(n-sz[u1])*sz[v],通过mp2来记录该信息,每处理完一个子结点时回溯更新,因为已经不在一条链上。

AC代码:

#include<cstdio>
#include<algorithm>
#include<unordered_map>
using namespace std; const int maxn=1e5+;
const int MOD=1e9+;
typedef long long LL;
typedef unordered_map<LL,LL> ump;
struct node{
int v,nex;
LL w;
}edge[maxn]; int n,head[maxn],cnt,sz[maxn];
LL val[maxn],ans;
ump sum,mp1,mp2; void adde(int u,int v,LL w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs1(int u,LL va){
val[u]=va,sz[u]=;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
LL w=edge[i].w;
dfs1(v,va^w);
sz[u]+=sz[v];
}
} void dfs2(int u){
ans=(ans+sum[val[u]]*sz[u])%MOD;
sum[val[u]]=(sum[val[u]]+sz[u])%MOD;
for(int i=head[u];i;i=edge[i].nex)
dfs2(edge[i].v);
} void dfs3(int u){
ans=(ans-mp1[val[u]]*sz[u]+mp2[val[u]]*sz[u]+MOD)%MOD;
mp1[val[u]]=(mp1[val[u]]+sz[u])%MOD;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
LL w=edge[i].w;
mp2[val[u]]=(mp2[val[u]]+n-sz[v]+MOD)%MOD;
dfs3(v);
mp2[val[u]]=(mp2[val[u]]-n+sz[v]+MOD)%MOD;
}
mp1[val[u]]=(mp1[val[u]]-sz[u]+MOD)%MOD;
} int main(){
scanf("%d",&n);
for(int i=;i<=n;++i){
int u;LL w;
scanf("%d%lld",&u,&w);
adde(u,i,w);
}
dfs1(,);
dfs2();
dfs3();
printf("%lld\n",ans);
return ;
}

最新文章

  1. linux系统下重启tomcat的shell脚本
  2. Feature Flag
  3. android.content.Context 含义及使用
  4. reduce + Promise 顺序执行代码
  5. 用JavaScript(js)对时间格式化
  6. cf703A Mishka and Game
  7. [Ext JS 4] 实战之Grid, Tree Gird 添加按钮列
  8. linux上ln命令详细说明
  9. C#避免过长的IF和Switch分支的方法
  10. Webkit之资源加载
  11. warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
  12. 实现去哪儿来回机票选择的view
  13. sqlzoo:2
  14. windows下面Nginx日志切割
  15. jmeter 写正则表达式
  16. 页面滚动图片等元素动态加载插件jquery.scrollLoading.js
  17. 给msde加装企业管理器
  18. 实验吧—安全杂项——WP之 你知道他是谁吗?
  19. mysql的一些 参数查询
  20. 工作总结 vue 城会玩

热门文章

  1. Leetcode部分题目整理(Javascript)
  2. plupload+上传文件夹
  3. (五)CWnd 所有窗口类的父类,CFrameWnd,Afx_xxx 全局函数,命名规范
  4. 初学mysql 如何删除数据库 如何安装mysql
  5. Java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配
  6. Android input输入框 移动页面input手机键盘中的“搜索”按键
  7. sql 查询存在一个表而不在另一个表中的数据
  8. 初步理解js作用域
  9. c语言求素数以及改进算法
  10. JAVA 基础编程练习题3 【程序 3 水仙花数】